链接:https://ac.nowcoder.com/acm/contest/392/J
思路:这道题范围给的很大,肯定不能用n*n的复杂度去写,最多只能 n*(logn), 因为子序列的字母之间是有先后关系的,我们先把母序列处理下,把每个字母的位置存到对应的vector里面,判断子序列时候合格时,我们遍历子序列每个字母,在当前字母对应的vector里二分取大于前一个字母位置的数,如果取不到那么这个子序列就不合格,如果取到了就保存下当前位置,继续遍历
实现代码:
#include<bits/stdc++.h> using namespace std; const int M = 1e6+10; vector<int>g[M]; int a[M]; int main() { string s,s1; int n; ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin>>s; for(int i = 0;i < s.size();i ++){ a[i] = s[i]-'a'; g[a[i]].push_back(i+1); } cin>>n; for(int i = 1;i <= n;i ++){ cin>>s1; int st = 0,flag = 0; for(int j = 0;j < s1.size();j ++){ int k = s1[j]-'a'; if(g[k].size()==0){ flag = 1;break; } int kk = upper_bound(g[k].begin(),g[k].end(),st) - g[k].begin(); if(kk >= g[k].size()){ flag = 1;break; } st = g[k][kk]; } if(!flag) cout<<"Yes"<<endl; else cout<<"No"<<endl; } }