• Educational Codeforces Round 81 (Rated for Div. 2) C. Obtain The String(序列自动机,贪心)


    [Educational Codeforces Round 81 (Rated for Div. 2) C. Obtain The String(序列自动机,贪心)

    C. Obtain The String

    time limit per test

    1 second

    memory limit per test

    256 megabytes

    input

    standard input

    output

    standard output

    You are given two strings ss and tt consisting of lowercase Latin letters. Also you have a string zz which is initially empty. You want string zz to be equal to string tt. You can perform the following operation to achieve this: append any subsequence of ss at the end of string zz. A subsequence is a sequence that can be derived from the given sequence by deleting zero or more elements without changing the order of the remaining elements. For example, if z=acz=ac, s=abcdes=abcde, you may turn zz into following strings in one operation:

    1. z=acacez=acace (if we choose subsequence aceace);
    2. z=acbcdz=acbcd (if we choose subsequence bcdbcd);
    3. z=acbcez=acbce (if we choose subsequence bcebce).

    Note that after this operation string ss doesn't change.

    Calculate the minimum number of such operations to turn string zz into string tt.

    Input

    The first line contains the integer TT (1≤T≤1001≤T≤100) — the number of test cases.

    The first line of each testcase contains one string ss (1≤|s|≤1051≤|s|≤105) consisting of lowercase Latin letters.

    The second line of each testcase contains one string tt (1≤|t|≤1051≤|t|≤105) consisting of lowercase Latin letters.

    It is guaranteed that the total length of all strings ss and tt in the input does not exceed 2⋅1052⋅105.

    Output

    For each testcase, print one integer — the minimum number of operations to turn string zz into string tt. If it's impossible print −1−1.

    Example

    input

    Copy

    3
    aabce
    ace
    abacaba
    aax
    ty
    yyt
    

    output

    Copy

    1
    -1
    3
    

    题意:

    t组数据,每一组数据含有一个字符串t和一个字符串s。

    x初始为空字符串,每一次操作可以在字符串x后面加一个s的子序列,问最少需要多少次操作可以使x等于t。

    思路:

    先标记字符串s中出现过哪些字符,然后如果有t中出现的字符,但是s中没有出现,答案就是-1,即不可能。

    然后通过dp的思想构建出序列自动机,就是一个数组(next[i][j]) 代表第i位之后最近的j字符的位置。

    然后通过贪心的思想即得出答案

    过程为:

    ​ 初始答案值ans为1,让字符串t通过数组next去匹配s,失配后ans加一,匹配的位置设为0。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <vector>
    #include <iomanip>
    #define ALL(x) (x).begin(), (x).end()
    #define sz(a) int(a.size())
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define pii pair<int,int>
    #define pll pair<long long ,long long>
    #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MSC0(X) memset((X), '', sizeof((X)))
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define eps 1e-6
    #define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
    #define du3(a,b,c) scanf("%d %d %d",&(a),&(b),&(c))
    #define du2(a,b) scanf("%d %d",&(a),&(b))
    #define du1(a) scanf("%d",&(a));
    using namespace std;
    typedef long long ll;
    ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
    ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
    ll powmod(ll a, ll b, ll MOD) { if (a == 0ll) {return 0ll;} a %= MOD; ll ans = 1; while (b) {if (b & 1) {ans = ans * a % MOD;} a = a * a % MOD; b >>= 1;} return ans;}
    void Pv(const vector<int> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%d", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("
    ");}}}
    void Pvl(const vector<ll> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%lld", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("
    ");}}}
    inline long long readll() {long long tmp = 0, fh = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') fh = -1; c = getchar();} while (c >= '0' && c <= '9') tmp = tmp * 10 + c - 48, c = getchar(); return tmp * fh;}
    inline int readint() {int tmp = 0, fh = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') fh = -1; c = getchar();} while (c >= '0' && c <= '9') tmp = tmp * 10 + c - 48, c = getchar(); return tmp * fh;}
    const int maxn = 1000010;
    const int inf = 0x3f3f3f3f;
    /*** TEMPLATE CODE * * STARTS HERE ***/
    int nxt[maxn][30];
    char s[maxn];
    int len;
    int len2;
    void init()
    {
        for (int i = len; i >= 1; --i)
        {
            repd(j, 0, 25)
            {
                nxt[i - 1][j] = nxt[i][j];
            }
            nxt[i - 1][s[i] - 'a'] = i;
        }
    }
    char t[maxn];
    bool vis[maxn];
    int a[maxn];
    void clear_()
    {
        for (int i = len; i >= 1; --i)
        {
            for (int j = 0; j <= 25; ++j)
            {
                nxt[i - 1][j] = 0;
            }
        }
    }
    int main()
    {
        //freopen("D:\code\text\input.txt","r",stdin);
        //freopen("D:\code\text\output.txt","w",stdout);
        int q;
        q = readint();
        while (q--)
        {
            // MS0(nxt);
            scanf("%s", s + 1);
            len = strlen(s + 1);
            init();
            repd(i, 'a', 'z')
            {
                vis[i] = 0;
            }
            repd(i, 1, len)
            {
                vis[s[i]] = 1;
            }
            scanf("%s", t + 1 );
            len2 = strlen(t + 1);
            int isok = 1;
            repd(i, 1, len2)
            {
                if (!vis[t[i]])
                {
                    isok = 0;
                    break;
                }
            }
            if (!isok)
            {
                printf("-1
    ");
                continue;
            }
            int ans = 1;
            for (int now = 0, i = 1; i <= len2; ++i)
            {
                now = nxt[now][t[i] - 'a'];
                if (!now)
                {
                    now = nxt[0][t[i] - 'a'];
                    ans++;
                }
            }
            printf("%d
    ", ans );
            clear_();
        }
        return 0;
    }
    
    
    
    
    本博客为本人原创,如需转载,请必须声明博客的源地址。 本人博客地址为:www.cnblogs.com/qieqiemin/ 希望所写的文章对您有帮助。
  • 相关阅读:
    Android开发学习笔记-关于Android的消息推送以及前后台切换
    C#文件操作工具类
    c#取得应用程序根目录
    Visual Studio 2012中使用GitHub
    C#邮件发送
    jquery判断某个属性是否存在 hasAttr
    js 如何让两个等长的数组产生键值对关系
    js判断一个元素是否在数组中
    日期控件
    react 生命周期函数的一些心得体会
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/12244355.html
Copyright © 2020-2023  润新知