https://vjudge.net/problem/CodeForces-1295C
题目大意:给定字符串
s
、
t
s、t
s、t,初始时字符串
z
z
z为空,每次操作可以把
s
s
s的任意一个子序列加到
z
z
z的末尾,问最少经过几次操作可以使
z
=
t
z=t
z=t,如果无法做到请输出
−
1
-1
−1。
思路:如果
t
t
t中的字符
s
s
s中没有,那么一定无解。考虑有解的情况,贪心的想一下,每一次操作肯定想在
z
z
z的末尾尽可能多加几个字符,那么每次选择自然要选取满足题意且在
s
s
s中最靠前的字符。不难想到用
v
e
c
[
26
]
[
m
a
x
l
e
n
]
vec[26][maxlen]
vec[26][maxlen]来存储每个字符出现的位置,然后用二分来模拟这个过程。
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
char s[maxn],t[maxn];
int a[26][maxn];
int len[26];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%s%s",s+1,t+1);
memset(len,0,sizeof(len));
int siz=strlen(s+1);
for(int i=1;i<=siz;i++)
a[s[i]-'a'][len[s[i]-'a']++]=i;
bool flag=0;
siz=strlen(t+1);
for(int i=1;i<=siz;i++)
{
if(len[t[i]-'a']==0)
{
flag=1;
break;
}
}
if(flag)
printf("-1\n");
else
{
int ans=0,idx=1;
int t1,t2,t3;
while(idx<=siz)
{
++ans;
t1=t[idx]-'a';
t2=a[t1][upper_bound(a[t1],a[t1]+len[t1],0)-a[t1]];
t1=t[++idx]-'a';
while(idx<=siz)
{
t3=upper_bound(a[t1],a[t1]+len[t1],t2)-a[t1];
if(t3==len[t1])
break;
t2=a[t1][t3];
t1=t[++idx]-'a';
}
}
printf("%d\n",ans);
}
}
return 0;
}