题目意思比较明了,匹配子串,我们很容易可以想到枚举全部的位置全部的字符,得到全部的子串序列去比较,但是这种枚举时间复杂度太大了,数据规模1e6,适当优化一下,通过O(n*26)预处理一下母串,从后往前,这样处理最终的到字母i在last数组里面的位置就是最前方,这个与BMH算法思路差不多。
#include <bits/stdc++.h> using namespace std; #define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0) typedef long long ll; inline int read() { int s = 0, w = 1; char ch = getchar(); while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); } while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar(); return s * w; } const int N = 1e6 + 7; char s[N], temp[N]; int len1, len2; int nxt[N][30]; int last[30]; //last[0]->a在字符串最前面出现的位置 void init() { memset(last, -1, sizeof(last));//初始化未出现 for (int i = len1; i >= 0; --i) { for (int j = 0; j < 26; ++j) nxt[i][j] = last[j];//nxt->i位置后字符'a'+j的位置 last[s[i] - 'a'] = i; //统计现在的字母位置 } } bool calc() { len2 = strlen(temp); int st = last[temp[0] - 'a']; //start为temp第一个字符位置 if (st == -1) return false; //第一个字符不在s中 for (int i = 1; i < len2; ++i) { st = nxt[st][temp[i] - 'a']; if (st == -1) return false; } return true; } int main() { scanf("%s", s); len1 = strlen(s); init(); int n = read(); while (n--) { scanf("%s", temp); if (calc()) puts("Yes"); else puts("No"); } return 0; }