【SSL】20210817A
题目描述
给出长度为n的字符串S,以及Q个询问
每个询问给出一个字符串T,判断T是否为S的一个子序列
所有串仅包含小写字母
30%:n<=1e4,q<=1e5
100%:
输入格式
第一行给出正整数n,Q
第二行给出S
接下来Q行,每行给出一个询问T
输出格式
对于每个询问输出一行表示答案,符合输出YES,不符输出NO
输入样例
3 1
abc
ac
输出样例
YES
解题思路
输入时用f[i,j]表示位置i以后字符j第一次出现的位置
然后预处理所有的f[i,j],然后暴力每次询问。
Code
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int mx=100100;
int n,q,tong[30][mx],lt[30],f[mx][30],lent;
string s,at;
int main()
{
scanf("%d%d",&n,&q);
cin>>s;
for(int i=0;i<n;++i)
{
tong[s[i]-96][++lt[s[i]-96]]=i;
}
for(int i=1;i<=26;++i)
{
int k=1;
for(int j=0;j<n;++j)
{
if(tong[i][k]<j) k++;
if(k>lt[i]) f[j][i]=-1;
else f[j][i]=tong[i][k];
}
}
for(int i=1;i<=q;++i)
{
cin>>at;
lent=at.size();
int k=0;
bool flag=true;
for(int j=0;j<lent;++j)
{
if(k<n&&f[k][at[j]-96]>=0)k=f[k][at[j]-96]+1;
else
{
flag=false;
break;
}
}
if(flag) printf("YES\n");
else printf("NO\n");
}
}