语言: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;
}

京公网安备 11010502036488号