语言:c++14 c++11会超时,但是c++14最多就100多ms,差了十倍多。
题解:我们用a[i][j]代表在第i个位置上时,第j个字母(一共26个字母,从0-25编号),距离此位置最近的位置时什么。
这样我们就免去了挨着遍历的复杂度,可以直接跳着来进行查找,如果在第i个位置之后的某个字母找不到,也就是说,构不成这样的一个字符串,我们们就可以打一个标记,直接跳出这一趟的查找,并输出No。
把么我们怎么构造这个数组呢。
我们首先初始化这个数组-1,然后从这个字符串的尾端往头开始递推。
递推关系式为:a[i][j]=a[i+1][j];
不要忘记每次更新一下他相邻的那个字符a[i][s[i+1]-'a']=i+1;
在最后还要更新一下第一个字符是什么a[0][s[0]-'a']=0;
/*Keep on going Never give up*/ #pragma GCC optimize(3,"Ofast","inline") #include <bits/stdc++.h> const int maxn = 1e6+10; const int MaxN = 0x3f3f3f3f; const int MinN = 0xc0c0c00c; typedef long long ll; const int mod = 100000000; using namespace std; char s[maxn],s1[maxn]; int a[maxn][27]; int main() { scanf("%s",s); int n; cin>>n; memset(a,-1,sizeof(a)); for(int i=strlen(s)-2;i>=0;i--){ for(int j=0;j<26;j++){ a[i][j]=a[i+1][j]; } a[i][s[i+1]-'a']=i+1; } a[0][s[0]-'a']=0; while(n--){ scanf("%s",s1); bool flag=true; int pos=0; for(int i=0;i<strlen(s1);i++){ pos=a[pos][s1[i]-'a']; if(pos==-1){ flag=false; break; } } if(flag) printf("Yes\n"); else printf("No\n"); } return 0; }