给你两个由小写拉丁字母组成的字符串s和t。此外,你还有一个最初为空的字符串z。你想让字符串z等于字符串t,你可以通过以下操作来实现:将s的任何子序列附加到字符串z的末尾。例如,如果z=ac,s=abcde,你可以通过一次操作将z变成以下字符串。
z=acace(如果我们选择子序列ace)。
z=acbcd(如果我们选择子序列bcd)。
z=acbce(如果我们选择子序列bce)。
请注意,在这个操作之后,字符串s不会改变。
计算将字符串z变成字符串t的最小操作次数。
输入
第一行包含整数T(1≤T≤100)--测试案例的数量。
每个测试案例的第一行包含一个由小写拉丁字母组成的字符串s(1≤|s|≤105)。
每个测试用例的第二行包含一个由小写拉丁字母组成的字符串t(1≤|t|≤105)。
保证输入中所有字符串s和t的总长度不超过2⋅105。
输出
对于每个测试案例,打印一个整数--将字符串z转化为字符串t的最少操作数,如果不可能则打印-1。
例子
inputCopy
3
aabce
ace
abacaba
aax
ty
yyt
outputCopy
1
-1
3
题意:给你s,t字符串,问最少几次可以用s的子序列构建出一个t字符串,不能输出-1
题解:把s中每个字母的下标存入vector中,遍历t如果当前字母没有,直接输出-1,否则找到大于上一次标记的是当前字符的下标,如果pos = 这个字符的个数说明下次要重新开始找,pos = 0,ans ++;
标记更新为当前找到的下标
#include<iostream>
#include<map>
#include<vector>
#include<string>
#include<map>
#include<algorithm>
using namespace std;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
string s1,s2;
cin>>s1>>s2;
vector<int> a[30];
for(int i = 0;i < s1.size(); i++)
{
a[s1[i]-'a'].push_back(i);
}
int ans = 1;
int cur = -1;
for(int i = 0;i < s2.size();i++)
{
int k = s2[i] - 'a';
if(!a[k].size())
{
ans = -1;
break;
}
int pos = upper_bound(a[k].begin(),a[k].end(),cur)-a[k].begin();
if(pos == a[k].size())
{
ans++;
pos = 0;
}
cur = a[k][pos];
}
printf("%d\n",ans);
}
}