【前言】本文以及之后的一些题解都会陆续整理到目录中,若想了解全部题解整理,请看这里:
第0002页 · 月月查华华的手机
不知道在看的各位有没有被家里人查过手机呢?如果有,想必今天你会感同身受一些。我们现在要来看一道比较有意思的题目,其中涉及到的字符查找的思想很有意义。话不多说,先看题目。
【月月查华华的手机】月月和华华一起去吃饭了。期间华华有事出去了一会儿,没有带手机。月月出于人类最单纯的好奇心,打开了华华的手机。哇,她看到了一片的QQ推荐好友,似乎华华还没有浏览过。月月顿时醋意大发,出于对好朋友的关心,为了避免华华浪费太多时间和其他网友聊天,她要删掉一些推荐好友。但是为了不让华华发现,产生猜疑,破坏了他们的友情,月月决定只删华华有可能搭讪的推荐好友。
月月熟知华华搭讪的规则。华华想与某个小姐姐搭讪,当且仅当小姐姐的昵称是他的昵称的子序列。为了方便,华华和小姐姐的昵称只由小写字母构成。为了更加方便,保证小姐姐的昵称长度不会比华华的长。
现在月月要快速的判断出哪些推荐好友要删掉,因为华华快回来了,时间紧迫,月月有点手忙脚乱,所以你赶紧写个程序帮帮她吧!其中要求:1 <= A <= 1e6 ; 1 <= N <= 1e6 ; 1 <= sum[Bi] <= 1e6。
IO要求 示例 输入描述:
第一行输入一个字符串A表示华华的昵称。
第二行输入一个正整数N表示华华的推荐好友的个数。
接下来N行,每行输入一个字符串Bi,Bi表示某个推荐好友的昵称。noiauwfaurainairtqltqlmomomo
8
rain
air
tql
ntt
xiaobai
oiiiooo
orzcnzcnznb
ooooo输出描述:
输出N行,对于第i个推荐好友,如果华华可能向她搭讪,输出Yes,否则输出No。
注意大写,同时也要注意输出效率对算法效率的影响。Yes
Yes
Yes
Yes
No
Yes
No
No
【解题分析】这道题目中需要我们对所有小姐姐的字符串在华华中查找一遍,判断是否是其子串。这里我们首先强调一个概念,在题目中没有说连续子字符串时,所谓的子串是可以不连续的,但是顺序要保持一致。
我们最开始的思路肯定是对每个小姐姐字符串都将华华字符串扫一遍,但此时根据所给数据范围,最坏情况下为 10^12。这是不可以的,因此,我们考虑如何快速地检索字符是本题的关键。
这里,我们给出的思路是:构造一个二维数组用来存储华华的每一位字符之后的下一个字符‘a’,'b','c',...... 分别在什么位置,这样就可以直接跳过中间的其余字符,大大减少检索遍历的次数,从而使最坏情况变为 10^6。这样就符合题目要求了。
有了思路,我们就来写代码了,一些细节部分会在代码中以注释的形式给出,请注意查收哦!
【源码展示】
#include <cstdio> #include <cstring> using namespace std; const int num = 1e6 + 10; // nex[][]用来存储每一位字符的下一个字符所在位置 // case[]用来不断刷新下一字符所在位置 int nex[num][30], cast[30]; int main() {char name[num];scanf("%s", name);int len = strlen(name);// 如果下一个字符,例如'a'不存在了,则它的下一个位置记为-1,表示不存在memset(cast, -1, sizeof(cast));// 将每个字符之后的下一个字符的位置存储下来// 从尾部开始遍历,这样就能确保每次刷新一个字符所在的位置即可// 但之前需要先把这个位置之后的字符位置存入nex[][]中再刷新cast[]for (int i = len - 1; i >= 0; i--) {for (int j = 0; j < 26; j++) {nex[i][j] = cast[j];}cast[name[i] - 'a'] = i;}int N;scanf("%d", &N);while (N--) {int flag = 1; // 1表示Yeschar girl[num];scanf("%s", girl);int len1 = strlen(girl);// pos用来记录按照小姐姐字符串的下一位字符在华华字符串中的位置// 如果出现pos == -1,那么就证明这个小姐姐不是华华的子串int pos = cast[girl[0] - 'a'];if (pos == -1) {printf("No\n");continue;}for (int i = 1; i < len1; i++) {pos = nex[pos][girl[i] - 'a'];if (pos == -1) {flag = 0;break;}}if (flag == 1) printf("Yes\n");else printf("No\n");}return 0; }