题目链接: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. 【Javaweb】JavaEE项目的三层架构 | 快速搭建

    逻辑类图 分层的目的是为了解耦.解耦就是为了降低代码的耦合度.方便项目后期的维护和升级. 不同的层有不同的包 web层 com.stguigu.web/servlet/controller servi ...

  2. 《最新出炉》系列初窥篇-Python+Playwright自动化测试-35-处理web页面定位toast-上篇

    1.简介 在使用appium写app自动化的时候介绍toast的相关元素的定位,在Web UI测试过程中,也经常遇到一些toast(出现之后一闪而过,不留下一点点痕迹),那么这个toast我们这边如何 ...

  3. ORCAD BOM制作

    1.导出BOM增加/TPCB Footpint和/tOptionnal 选项 2.器件选焊的optionnal设置/X符号, 3.导出BOM后选择/X的,删除,不出现加工的BOM中

  4. [CF403E]Two Rooted Trees

    Two Rooted Trees 题面翻译 题目描述 你有两棵有根树,每棵树都有 \(n\) 个结点.不妨将这两棵树上的点都用 \(1\) 到 \(n\) 之间的整数编号.每棵树的根结点都是 \(1\ ...

  5. MybatisPlus高级特性之SimpleQuery工具类

    1.是很么? SimpleQuery可以对selectList查询后的结果使用Stream流进行操作,使其可以返回指定的结果,简洁了api的调用 2.怎么玩? 案例演示 (1) list操作 /** ...

  6. AVL树和红黑树的Python代码实现

    AVL树 AVL树是一种自平衡二叉搜索树.在这种树中,任何节点的两个子树的高度差被严格控制在1以内.这确保了树的平衡,从而保证了搜索.插入和删除操作的高效性.AVL树是由Georgy Adelson- ...

  7. [Luogu 4912 帕秋莉的魔法] 题解报告

    算法:DP, 背包,动态规划 简化版题目: 给定 \(n\) 个物品,物品的价值为 \(v_1 - v_n\),物品的体积为 \(w_1 - w_n\).需要选择一些物品,使它们的体积和为 \(V\) ...

  8. 快速批量升级 NugetPackage 版本

    批量升级项目中的 Nuget 有时候我们需要升级整个解决方案中的某些Nuget版本,如果每个手动使用NuGet Package Manager 会很麻烦.经过一个周末的踩坑,我找到一个解决方案. Na ...

  9. 华为云API Explorer:自动化运维的得力助手

    华为云API Explorer为开发者提供一站式API解决方案统一平台,集成华为云服务所有开放API,支持全量快速检索.可视化调试.帮助文档.代码示例等能力,帮助开发者快速学习API,使用API开发代 ...

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

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