题目意思比较明了,匹配子串,我们很容易可以想到枚举全部的位置全部的字符,得到全部的子串序列去比较,但是这种枚举时间复杂度太大了,数据规模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;
}
京公网安备 11010502036488号