题目链接:Here

题意总结:\(N\) 次查询串 \(B\) 是否是 \(A\) 的子序列。

思路一

个人做法,枚举原字符串的每一位,如果匹配当前字符串的字符则 m++ 直到字符串枚举完毕或者 m >= t.size()

  • \(\mathcal{O}(N)\)
string s, t;
void solve() {
cin >> t;
int m = 0;
for (int i = 0; i < s.size(); ++i) {
if (s[i] == t[m]) m++;
if (m >= t.size()) break;
}
cout << (m >= t.size() ? "Yes" : "No") << "\n";
}
int main() {
ios_base::sync_with_stdio(false), cin.tie(0);
int _;
cin >> s;
for (cin >> _; _--;) solve();
return 0;
}

博客这么结束就太短了,AC之后看了下其他人的解法。发现还有一些好解法,如下介绍:

思路二

预处理 \(A\) 串每个位置后,每个字母首次出现的位置。

\(tp[i][j]\) 表示A串第\(i\)个位置后,字符\(j\)首次出现的位置。从后往前扫一遍就出来了。

时间复杂度:\(\mathcal{O}(26|A|)\)

查询每个串B时用 \(tp\) 数组在A上跳。N次查询复杂度 \(\mathcal{O}(\sum_{i = 1}^N|B|)\)

这样做空间、时间复杂度是 O(2.6e7)。但是它过了。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6 + 7;
char s[N];
int tp[N][26];
int main(void) {
scanf("%s", s + 1);
int n = strlen(s + 1);
for (int i = n - 1; i >= 0; --i) {
for (int j = 0; j < 26; ++j) tp[i][j] = tp[i + 1][j];
tp[i][s[i + 1] - 'a'] = i + 1;
}
int q;
scanf("%d", &q);
while (q--) {
scanf("%s", s + 1);
int m = strlen(s + 1);
int pos = 0, flag = 1;
for (int i = 1; i <= m; ++i) {
if (tp[pos][s[i] - 'a']) {
pos = tp[pos][s[i] - 'a'];
} else {
flag = 0;
break;
}
}
cout << (flag ? "Yes" : "No") << "\n";
}
return 0;
}

思路三:序列自动机

序列自动机的构建的核心在于 \(next\) 数组

\(next_{i,j}\) 代表位置 \(i\) 后字符 \(j\) 第一次出现的位置。

当从位置 \(i + 1\) 移动到 i 时,显然只有一个字符的 next 值发生了变化

操作代码

void Build(void) {
n = strlen(s + 1);
for (int i = n; i >= 1; i--) {
for (int j = 0; j < 26; j++) fail[i - 1][j] = fail[i][j];
fail[i - 1][s[i] - 'a'] = i;
}
}

序列自动机的查找

从头向后移动匹配,一旦失配,直接失败。

bool check(void) {
int m = strlen(t + 1), pos = 0;
for(int i = 1; i <= m; i++) {
pos = fail[pos][t[i] - 'a'];
if(!pos) return false;
}
return true;
}

不难发现,这个题就是个模板题,粘贴好模板就行了。

#include <bits/stdc++.h>
using namespace std;
const int maxs = 1000000 + 7;
int n, T;
char s[maxs], t[maxs];
int fail[maxs][28];
void Build(void) {
n = strlen(s + 1);
for (int i = n; i >= 1; i--) {
for (int j = 0; j < 26; j++) fail[i - 1][j] = fail[i][j];
fail[i - 1][s[i] - 'a'] = i;
}
}
bool check(void) {
int m = strlen(t + 1), pos = 0;
for (int i = 1; i <= m; i++) {
pos = fail[pos][t[i] - 'a'];
if (!pos) return false;
}
return true;
}
int main(void) {
scanf("%s", s + 1);
Build();
scanf("%d", &T);
while (T--) {
scanf("%s", t + 1);
cout << (check() ? "Yes" : "No") << "\n";
}
return 0;
}

【每日一题】7.月月查华华的手机 (枚举 or 序列自动机)的更多相关文章

  1. 【python】Leetcode每日一题-132模式

    [python]Leetcode每日一题-132模式 [题目描述] 给定一个整数序列:a1, a2, ..., an,一个132模式的子序列 ai, aj, ak 被定义为:当 i < j &l ...

  2. 牛客小白月赛12 J 月月查华华的手机 (序列自动机模板题)

    链接:https://ac.nowcoder.com/acm/contest/392/J 来源:牛客网 题目描述 月月和华华一起去吃饭了.期间华华有事出去了一会儿,没有带手机.月月出于人类最单纯的好奇 ...

  3. NC23053 月月查华华的手机

    NC23053 月月查华华的手机 题目 题目描述 月月和华华一起去吃饭了.期间华华有事出去了一会儿,没有带手机.月月出于人类最单纯的好奇心,打开了华华的手机.哇,她看到了一片的QQ推荐好友,似乎华华还 ...

  4. 牛客小白月赛12 J 月月查华华的手机(序列自动机)

    ---恢复内容开始--- 题目来源:https://ac.nowcoder.com/acm/contest/392/J 题意: 题目描述 月月和华华一起去吃饭了.期间华华有事出去了一会儿,没有带手机. ...

  5. Newcoder 华华给月月出题(线筛)题解

    题目描述: 华华刚刚帮月月完成了作业.为了展示自己的学习水平之高超,华华还给月月出了一道类似的题: Ans=⊕Ni=1(iNmod(109+7))Ans=⊕i=1N(iNmod(109+7)) ⊕⊕符 ...

  6. 牛客小白月赛12 D 月月给华华出题 (欧拉函数,数论,线筛)

    链接:https://ac.nowcoder.com/acm/contest/392/D 来源:牛客网 月月给华华出题 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 131072K, ...

  7. 牛客小白月赛12 C 华华给月月出题 (积性函数,线性筛)

    链接:https://ac.nowcoder.com/acm/contest/392/C 来源:牛客网 华华给月月出题 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 131072K, ...

  8. 【ACM算法竞赛日常训练】DAY10题解与分析【月月给华华出题】【华华给月月出题】| 筛法 | 欧拉函数 | 数论

    DAY10共2题: 月月给华华出题 华华给月月出题 难度较大. 作者:Eriktse 简介:211计算机在读,现役ACM银牌选手力争以通俗易懂的方式讲解算法!️欢迎关注我,一起交流C++/Python ...

  9. 牛客网 牛客小白月赛12 B.华华教月月做数学-A^B mod P-快速幂+快速乘

    链接:https://ac.nowcoder.com/acm/contest/392/B来源:牛客网 华华教月月做数学 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其 ...

  10. E.华华给月月准备礼物

    链接:https://ac.nowcoder.com/acm/contest/392/E 题意: 二月中旬虐狗节前夕,华华决定给月月准备一份礼物.为了搭建礼物的底座,华华需要若干根同样长的木棍.华华手 ...

随机推荐

  1. 配置postcss-pxtorem报:options has an unknown property 'plugins'

    闲聊: 小颖最近在坐大屏相关的项目,要写适配,之前用的:postcss-px2rem.px2rem-loader,和朋友闲聊呢他说他们也在写大屏,不过他们用的 postcss-pxtorem,在写另外 ...

  2. 简易的git命令行入门教程

    一.Git 全局设置 git config --global user.name "用户名" git config --global user.email "邮件地址@1 ...

  3. 光学测量 PPG

    参考来源:ADI官网技术文章.知乎(hxl695822705.KingPo-张超.深圳加1健康科技 ) 现状 PPG测量心率.血氧的技术距今发展快100年,影响心率.血氧测量准确度的因素主要有心率传感 ...

  4. Object类、String和StringBuffer、Math类、日期处理类

    1.Object类 "万物皆对象":(1)从类和对象角度:任何具体事物都是一个对象,. (2)Object类,类似"东西".所有的类都继承了Object类. 使 ...

  5. 从零玩转人脸识别验证-face

    title: 从零玩转人脸识别验证 date: 2022-05-15 21:05:52.974 updated: 2023-05-16 00:00:11.594 url: https://www.yb ...

  6. 平衡树——AVL算法

    平衡树--AVL算法 平衡树建立在二叉搜索树的基础上,加入了两侧子树大小相对平衡的特性而避免了很多情况下的算法退化.这里AVL算法实现的AVL树就是平衡树的一种. 1.二叉搜索树 在说平衡树之前我们得 ...

  7. Cesium案例解析(十)——CZML点

    目录 1. 概述 2. 案例 3. 结果 1. 概述 CZML是Cesium中用于描述动态图形场景的JSON格式,它们的关系类似于Google Earth与KML之间的关系,一般会认为KML是一种矢量 ...

  8. 实战案例丨代码优化:如何去除context中的warning?

    在一个java语言群里面,有人抛了这么一段代码出来,问题是出现了下下图中的warning,问有什么好的方法消除 这种强转都是因为类型链条断掉了,写入的时候擦除了类型,读出来的时候也就只能强转了,那个i ...

  9. 技术实操丨SoundNet迁移学习之由声音分类到语音情感识别

    摘要:声音也是识别对象的一种重要数据源.其中根据声音来识别声音所处的环境也是语音识别的研究内容之一. 一.思路 1.SoundNet模型在视频数据中先预训练,视频任务可能是场景识别,可参考这篇文章So ...

  10. 你应该知道的数仓安全——默认权限实现共享schema

    摘要: 一种典型客户场景是一些用户是数据的生产方,需要在schema中创建表并写入数据:而另一些用户是数据的消费方,读取schema中的数据做分析.使用Alter default privilege语 ...