牛客小白月赛12J(序列自动机)
题目链接:https://ac.nowcoder.com/acm/contest/392/J
题目大意:给一个字符串s,然后在给出n个其他的字符串,判断每个字符串是否为s的子序列。
例:
输入:
noiauwfaurainairtqltqlmomomo
8
rain
air
tql
ntt
xiaobai
oiiiooo
orzcnzcnznb
ooooo
输出:
Yes
Yes
Yes
Yes
No
Yes
No
No
解题思路:序列自动机,对字符串s预处理出在每个位置,下一个字符出现的位置,匹配的时候就从前往后匹配,看是否可以一直匹配下去,如果可以输出Yes,否则输出No。单次查询的复杂度是O(|Bi|)O(|Bi|)的,序列自动机预处理的复杂度是O(26|A|)的。总时间复杂度是O(26|A|+∑Ni=1|Bi|)O(26|A|+∑i=1N|Bi|)
代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=1e6+10; char s[maxn],b[maxn]; int Next[maxn][26]; int n; int main(){ scanf("%s",s+1); scanf("%d",&n); int len=strlen(s+1); for(int i=len;i>=1;i--){ for(int j=0;j<26;j++) Next[i-1][j]=Next[i][j]; Next[i-1][s[i]-'a']=i; } while(n--){ scanf("%s",b); int flag=0,pos=0,len1=strlen(b);; for(int i=0;i<len1;i++){ if(Next[pos][b[i]-'a']) pos=Next[pos][b[i]-'a']; else{ flag=1; break; } } if(flag)puts("No"); else puts("Yes"); } return 0; }