
月月和华华一起去吃饭了。期间华华有事出去了一会儿,没有带手机。月月出于人类最单纯的好奇心,打开了华华的手机。哇,她看到了一片的QQ推荐好友,似乎华华还没有浏览过。月月顿时醋意大发,出于对好朋友的关心,为了避免华华浪费太多时间和其他网友聊天,她要删掉一些推荐好友。但是为了不让华华发现,产生猜疑,破坏了他们的友情,月月决定只删华华有可能搭讪的推荐好友。
月月熟知华华搭讪的规则。华华想与某个小姐姐搭讪,当且仅当小姐姐的昵称是他的昵称的子序列。为了方便,华华和小姐姐的昵称只由小写字母构成。为了更加方便,保证小姐姐的昵称长度不会比华华的长。
现在月月要快速的判断出哪些推荐好友要删掉,因为华华快回来了,时间紧迫,月月有点手忙脚乱,所以你赶紧写个程序帮帮她吧!
题目
- 原题地址:月月查华华的手机
- 题目编号:NC23053
- 题目类型:指针优化
- 时间限制:C/C++ 2秒,其他语言4秒
- 空间限制:C/C++ 262144K,其他语言524288K
1.题目大意
- 给定一个小写字母串 S,给出 n 个查询字符串,问是否是 S 的子序列。
2.题目分析
- 避免逐个匹配的问题,为 S 的每个字符增加指针,即该位置后面的字母第一次出现的位置
- 例:
nexta[5][3] = 8
的含义为str[5]
后面的第一次出现的字母d
('d'-'a'=3)是str[8]
- 每次只要依次寻找子字符串
tmp
中的字母即可,只要子串的最后一个字母存在(即nexta[k][tmp[i]-'a']!=0
)就判断符合
3.题目代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
int nexta[N][26];
string str = "";
void handle()
{
for(int i=str.length()-2;i>=0;i--)
{
for(int j=0;j<26;j++)
nexta[i][j] = nexta[i+1][j];
nexta[i][str[i+1]-'a'] = i+1;
}
}
int main() {
cin >> str;
str = " " + str;
handle();
int t;
cin >> t;
string tmp;
while(t--)
{
cin >> tmp;
int k = 0;
int flag = 0;
for(int i=0;i<tmp.length();i++)
{
k = nexta[k][tmp[i]-'a'];
if(!k)
{
flag = 1;
break;
}
}
if(flag)
cout << "No" << endl;
else
cout << "Yes" << endl;
}
}