• 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/ 希望所写的文章对您有帮助。
  • 相关阅读:
    CAPTCHA---验证码 ---Security code
    Thymeleaf利用layout.html文件生成页面布局框架
    阿里云和腾讯云免费SSL证书 专题
    完整项目基础架构精简版-实现权限管理
    Android 基于XMPP Smack openfire 开发的聊天室
    Android 基于Bmob平台数据管理常用方法整理
    Android图表和图形创建库:EazeGraph
    Android 使用开源库StickyGridHeaders来实现带sections和headers的GridView显示本地图片效果
    Android MagicIndicator系列之一 —— 使用MagicIndicator打造千变万化的ViewPager指示器
    Android 比较两个时间段是否有交集或重复
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/12244355.html
Copyright © 2020-2023  润新知