牛客小白月赛12J-月月查华华的手机-(思维)
https://ac.nowcoder.com/acm/contest/392/J
题意:判断一个子串是不是母串的子序列。len<=1e6。
思路:子序列不要求连续,可以跳跃性地寻找,例如abcdefg,查找ag,找到a不需要找bcdef,直接找g是否存在。对于当前字符,记录 下一个特定字符 在第一次出现时的下标,这样就可以将子序列连接起来,打表从后往前。
#include<stdio.h> #include<iostream> #include<algorithm> #include<cstring> #include<math.h> #include<string> #include<map> #include<queue> #include<stack> #include<set> #define ll long long #define inf 0x3f3f3f3f using namespace std; char a[1000086]; char b[1000086]; int next1[1000086][26]; int nextt[30];///下一个指定字符的位置 int n,m; void init()///初始化打表 { for(int i=n;i>=1;i--) { for(int j=0;j<26;j++) next1[i][j]=nextt[j]; int x=a[i]-'a'; nextt[x]=i; } } bool check() { int len=strlen(b+1); if(len==1) { if(nextt[ b[1]-'a' ]!=0) return true; else return false; } int now=2; int i=nextt[ b[1]-'a' ];///第一个字母在原串之中的位置 int j=b[now]-'a'; while(i!=0 && next1[i][j]!=0) { i=next1[i][j];///i跳到那一步取 now++; if(now>len) return true; if(now) j=b[now]-'a'; } return false; } int main() { scanf("%s",a+1); n=strlen(a+1); init(); scanf("%d",&m); while(m--) { scanf("%s",b+1); if(check()) printf("Yes\n"); else printf("No\n"); } return 0; }