1295C Obtain The String

You are given two strings s and t consisting of lowercase Latin
letters. Also you have a string z which is initially empty. You want
string z to be equal to string t. You can perform the following
operation to achieve this: append any subsequence of s at the end of
string z. 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=ac, s=abcde, you
may turn z into following strings in one operation:

z=acace (if we choose subsequence ace); z=acbcd (if we choose
subsequence bcd); z=acbce (if we choose subsequence bce). Note that
after this operation string s doesn’t change.

Calculate the minimum number of such operations to turn string z into
string t.

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

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

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

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

Output For each testcase, print one integer — the minimum number of
operations to turn string z into string t. If it’s impossible print
−1.
传送门

给定一个字符串s,空字符串z,每次取这个字符串s的子串与z相加,问形成目标字符串t的最少操作次数
首先处理原有的字符串s,把s的每个字母的出现次数和出现位置保存下来
然后遍历字符串t,如果t中存在s中没有的字母则输出-1,否则:
补充前提1:每次找到符合要求的点之后就记录它的下标p
若p的下标大于等于字符串t对应的字母的最后出现下标,那么就不能在本次操作中取完了,需要进行新的操作

#include <bits/stdc++.h>

using namespace std;
int nums[26];//记录每个字母的出现次数
int main()
{
    ios::sync_with_stdio(0);
    int _;//很cool的用法
    cin>>_;
    string s,t;
    while(_--){
        cin>>s>>t;
        int p,ans;
        bool opt=1;
        ans=1;
        p=-1;
        vector<int> rec[26];//记录每个字母出现的位置
        memset(nums,0,sizeof nums);
        for(int i=0;i<s.size();i++){
            rec[s[i]-'a'].push_back(i);
            nums[s[i]-'a']++;
        }
        for(int i=0;i<t.size();i++){
            if(nums[t[i]-'a']==0){//未出现则停止循环
                cout<<-1<<endl;
                opt=0;
                break;
            }
            if(p>=rec[t[i]-'a'][nums[t[i]-'a']-1]){
                ans++;
                p=rec[t[i]-'a'][0];//从第一次出现的地方开始
            }
            else{
                int key0;
 key0=upper_bound(rec[t[i]-'a'].begin(),rec[t[i]-'a'].end(),p)-rec[t[i]-'a'].begin();
               //寻找出适合的p的位置
                p=rec[t[i]-'a'][key0];
            }
        }
        if(opt)cout<<ans<<endl;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值