CF1295C Obtain the String

题意:

给出两个串s和t,每次操作可以选择s中的一个子序列拼到z串后,z串一开始是空的,询问至少操作几次可以使得z串变成t串

题解:

预处理思维题,我太菜了,这都不会做...

定义一个二维数组nxt,表示s中第i-1个字符后面要跟第j个字母的话,应该去哪个位置(比较难懂...)

然后先初始化所有边界值为-1

倒着遍历s串,预处理整个二维数组

然后遍历t串,定义一个指针同时遍历s串

如果对应二维数组的值存在,那么指针直接移到那个位置

否则次数加一,指针置为0

时间复杂度是O(26*M)=O(M)

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+100;
string s,t;
int T;
int nxt[maxn][30];
int main () {
    scanf("%d",&T);
    while (T--) {
        cin>>s>>t;
        int len=s.length();
        for (int i=0;i<26;i++) 
            nxt[len][i]=-1;
        for (int i=len-1;i>=0;i--) {
            for (int j=0;j<26;j++) 
                nxt[i][j]=nxt[i+1][j];
            nxt[i][s[i]-'a']=i+1;
        }
        int ans=1;
        int tot=0;
        int f=1;
        for (int i=0;i<t.length();i++) {
            if (nxt[tot][t[i]-'a']!=-1) 
                tot=nxt[tot][t[i]-'a'];
            else {
                ans++;
                tot=0;
                if (nxt[0][t[i]-'a']==-1) {
                    f=0;break;
                }
                tot=nxt[tot][t[i]-'a'];
            }
        }
        if (!f) 
            printf("-1\n");
        else 
            printf("%d\n",ans);
    }
}

 

posted @ 2020-04-03 14:00  zlc0405  阅读(177)  评论(0编辑  收藏  举报