题目分析
1.这个题目如果直接暴力那么时间复杂度太大,那么我们可以用优化方法,直接跳转到后面的字符一一比较,只要有一个不符合,那么就return 0;
2.我们开两个数组,用last数组不断地更新a字符串每个位置的字母,再把它赋给二维数组nec,我们用nec数组来记录每一个字母后面字母出现的相应位置
3.为什么要从后面开始遍历,以为这样非常方便的更新last数组的值,每往前一位,就再次重新赋给当前的nec数组
4.如果匹配的时候,没有与比较字符相同的,那么当前位置所存贮的数就是-1,我们就直接返回0

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 10;
char a[maxn], b[maxn];
int n, last[30], nec[maxn][30];
void deal()
{
    memset(last, -1, sizeof(last)); //初始化标记
    int la = strlen(a);
    for (int i = la - 1; i >= 0; --i) //从后往前遍历,方便填数
    {
        for (int k = 0; k < 26; ++k)
            nec[i][k] = last[k]; //赋值给当前的nec数组
        last[a[i] - 'a'] = i;    //用当前字母修改last
    }
}
bool judge()
{
    int la = strlen(a);
    int lb = strlen(b);
    int i = last[b[0] - 'a']; //i初值直接赋为A中子串首字母的位置
    if (i == -1)
        return 0;                //如果A中没有这个首字母 直接无解
    for (int j = 1; j < lb; ++j) //从第二个字母开始遍历因为首字母已经完成了赋值与判断
    {
        i = nec[i][b[j] - 'a']; //直接跳转
        if (i == -1)
            return 0;
    }
    return 1;
}
int main()
{
    scanf("%s", a);
    deal();
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i)
    {
        scanf("%s", b);
        if (judge())
            printf("Yes\n");
        else
            printf("No\n");
    }
    return 0;
}