思路:
设主串为S,判断模式串是不是S的子序列?
贪心考虑,从左到右扫一遍S,如果当前字符在S中出现,那么我就找到S中最先出现的位置A1,然后我们下次找的位置要大于A1,以此类推。
复杂度分析
二分查找 + 枚举 = O( )
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e6 + 5; vector<int> pos[30]; char s[maxn], tmp[maxn]; int n, m; bool solve(){ int ind = -1; for(int i = 1; i <= n; i++){ int f = tmp[i] - 'a'; ind = upper_bound(pos[f].begin(), pos[f].end(), ind) - pos[f].begin(); if(ind == pos[f].end() - pos[f].begin()) return false; ind = pos[f][ind]; } return true; } int main(){ //pos[0].push_back(1); pos[0].push_back(2); pos[0].push_back(3); //cout << (upper_bound(pos[0].begin(), pos[0].end(), -1) - pos[0].begin()) << endl; scanf("%s", s + 1); n = strlen(s + 1); for(int i = 1; i <= n; i++){ pos[s[i] - 'a'].push_back(i); } scanf("%d", &m); while(m--){ scanf("%s", tmp + 1); n = strlen(tmp + 1); if(solve()){ puts("Yes"); } else{ puts("No"); } } return 0; }