[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:
- z=acacez=acace (if we choose subsequence aceace);
- z=acbcdz=acbcd (if we choose subsequence bcdbcd);
- 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), '\0', 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("\n");}}}
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("\n");}}}
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\n");
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\n", ans );
clear_();
}
return 0;
}