cf.Obtain The String

**

题意:

**
首先说一下题意,输入T,代表测试样例的个数,每个测试样例包含两个字符串s和t,设z是个空的字符串,你可以从s里从前到后按顺序拿出字符串放到z的末尾,然后记拿出的次数为res,如果不可能达到则res等于-1。

思想:
理解完题意,就开始我们的思路。
首先我们记录s和t的长度分别为n,m,然后我们记录p数组n行的每个字母都是-1,然后就从n-1开始向前找,用dp的思想,p[i][j] = p[i+1][j],然后刷新他最先出现的位置,p[i][a[i]-‘a’] = i。储存完了之后就开始找答案了,如果0行都是-1的话,说明从未出现过,那么无论如何也达不到。如果有的话,每次我们就从上一个字母的位置往后寻找,如果后面没有,就只好从头再找,然后输出结果就可。

加粗样式下面附上代码,加强理解:

#include<iostream>
#include<stdlib.h>
#include<bits/stdc++.h>
#include<stdio.h>
using namespace std;
const int N = 1e5+10;
char a[100005] , b[100005];
long long p[100005][26],n,m;
int main()
{
	long long int t;
	scanf("%lld",&t);
	while(t--)
	{
		scanf("%s",a);
		scanf("%s",b);
		n = strlen(a);
		m = strlen(b);
		for(int i = 0 ; i < 26 ; i++)
		{
			p[n][i] = -1;
		} 
		for(int i = n-1 ; i >= 0 ; i--)
		{
			for(int j = 0 ; j < 26 ; j++)
			{
				p[i][j] = p[i+1][j];
			}
			p[i][a[i]-'a'] = i;
		}
		long long int ans = 1 , pe = 0 , flag = 0;
		while(pe < m)
		{
			if(p[flag][b[pe]-'a']==-1)
			{
				if(flag == 0)
				{
					ans = -1;
					break;
				}
				else
				{
					flag = 0 , ans++;
					continue;
				}
			}
			flag = p[flag][b[pe]-'a']+1;
			pe++;
		}
		printf("%d\n",ans);
	}
	return 0;
}
发布了107 篇原创文章 · 获赞 3 · 访问量 7117

猜你喜欢

转载自blog.csdn.net/qq_43504141/article/details/104136937