Educational Codeforces Round 81 (Rated for Div. 2)C. Obtain The String

原题:C. 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.

Example
inputCopy
3
aabce
ace
abacaba
aax
ty
yyt
outputCopy
1
-1
3
解:水题嘛!不能太暴力会超时。后来看的时候觉得网上有些朋友们的想法值得借鉴~所以这边给出两种解法。(超随意)
one:

#include
#include
#include
#include
#include
#include
#include
#include
#include 
#include
#include
#include
#include 
#include
using namespace std;
int nt[100010][30];
int main(){
    int T,n,x;
	string s,t;
    cin>>T;
    while(T--){
        cin>>s>>t;
        int sum=s.size();
        for(int i=0;i<26;i++) 
			nt[sum][i]=-1;
        for (int i=sum-1;i>=0;i--){//从最后开始往前推进,更新目前位置到要求的数字的最近地点 
            for(int j=0;j<26;j++) 
			nt[i][j]=nt[i+1][j];
            int key=s[i]-'a';
            nt[i][key]=i+1;
        }
        sum=t.size();
        int cnt=1,tt=0;
        bool flag=true;
        for (int i=0;i<sum;i++){
            int kk=t[i]-'a';
            if (nt[tt][kk]!=-1){
                tt=nt[tt][kk];
            }
			else{
                cnt++;//从这位置没有,次数加一,回到0位置看有没有,没有则不成立 
                tt=0;
                if(nt[0][kk]==-1){
                    flag=false;
                    break;
                }
                tt=nt[tt][kk];
            }
        }
        if(!flag) 
		cout<<-1<<endl;
		else
        cout<<cnt<<endl;
    }
    return 0;
}

two:

#include
#include
#include
#include
#include
#include
#include
#include
#include 
#include
#include
#include
#include 
#include
using namespace std;
vector<int>v[26];//字母出现的位置 
int main(){
	string s,t;
	int T;
	cin>>T;
	while(T--){
		cin>>s>>t;
		for(int i=0;i<26;i++) 
		v[i].clear();
		for(int i=0;i<s.size();i++) 
		v[s[i]-'a'].push_back(i);//依次推入位置 
		int cnt=1,k=0;
		for(int i=0;i<t.size();i++){
			int x=t[i]-'a';
			int sum=v[x].size();
			int l=lower_bound(v[x].begin(),v[x].end(),k)-v[x].begin();//二分找位置 
			if(!sum){
				cnt=-1;
				break;
			}
			else if(l==sum){
				k=0;
				cnt++;
				i--;
			} 
			else k=v[x][l]+1;//从这位置继续找 
		}
		cout<<cnt<<endl;
	}
	return 0;
}

你可能感兴趣的:(Educational Codeforces Round 81 (Rated for Div. 2)C. Obtain The String)