牛客小白月赛12 J 月月查华华的手机

链接: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;
    }
}

猜你喜欢

转载自www.cnblogs.com/kls123/p/10503085.html