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