牛客小白月赛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;
}

 

posted @ 2019-03-12 16:57  两点够吗  阅读(174)  评论(0编辑  收藏  举报