思路:
由于数据范围达到1e6,暴力做法时间复杂度显然离谱。
我们考虑优化查找这一过程,不难想到维护一个数组 f[0-s.size]['a'-'z'],用来表示第i个字符后面第一次出现的'a'-'z'的位置,这样一来我们在查找的时候就只需要判断该字符是否在上一个字符右边出现即可,然后跳转到对应位置。
关于f数组的维护,我们从后往前遍历字符串,数组pre['a'-'z']表示最后一次出现该字符的位置,以此来维护f数组。
时间复杂度:O(26*s.size)
#include using namespace std; const int N = 1e6 + 5; int n, pre[26], f[N][26]; char s[N], t[N]; int main() { cin >> s + 1 >> n; for (int i = strlen(s + 1); i; i--) { for (int j = 0; j < 26; j++) f[i][j] = pre[j]; pre[s[i] - 'a'] = i; } while (n--) { cin >> t; int pos = pre[t[0] - 'a']; bool flag = false; if (!pos) flag = true; else { for (int i = 1; t[i]; i++) { if (!f[pos][t[i] - 'a']) { flag = true; break; } pos = f[pos][t[i] - 'a']; } } if (flag) cout<<"No\n"; else cout<<"Yes\n"; } return 0; }