•题意
给出一个只包含小写字母的串 s 和n 个串t,判断t[i]是否为串 s 的子序列;
如果是,输出"YES",反之,输出"NO";
•思路
可以把s串中每一个字母的位置预处理出来。(由于总长度是1e5,可能有26个字母,用数组存[26][100000]显然是不可能的,所以就用vector动态分配一下(QwQ)
然后设置一个指针cur,指向当前字母的位置。
再开一个数组记录一下使用后的每个字母的最后一个位置,为了避免每次从第一个开始找。
•代码
View Code#include<bits/stdc++.h> using namespace std; const int maxn=100000+5; vector<int> p[27]; char s[maxn]; char t[maxn]; int a[27];//记录使用后的每个字母的最后一个位置,即这个字母到达的最远的位置 //后面再找这个字母时,从这个位置的下一个开始找,可以减少查找量 int main() { scanf("%s",s); int n=strlen(s); for(int i=0;i<n;i++) p[s[i]-'a'].push_back(i);//预处理s串每个字母的位置 int kase; scanf("%d",&kase); while(kase--) { memset(a,0,sizeof a); int cur=-1;//初始化为-1 因为从0开始 scanf("%s",t); int m=strlen(t); int flag;//判断每个字母能不能找到符合要求的 for(int i=0;i<m;i++) { flag=0; int x=t[i]-'a'; for(int j=a[x];j<p[x].size();j++) { if(p[x][j]>cur)//在s串中找x出现的位置 >cur 的第一个位置,有点贪心的感jio { cur=p[x][j];//更新cur a[x]=j+1;//记录之前x到达的最远位置j,后面从j+1开始找 flag=1; break; } } if(!flag)//没找到需要的字母,肯定t串就不存在 break; } if(!flag) printf("NO\n"); else printf("YES\n"); } }