QDU 6-GZS and String-字符串匹配的思维题

Description

GZS has two strings s and t.

In each step, GZS can select arbitrary character c of s and insert any character d (d ≠ c) just after it.

GZS wants to convert s to t. But is it possible?

Input

There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case there are two strings s and t, one per line. 1 ≤ T ≤ 105 1 ≤ |s| ≤ |t| ≤ 105 All strings consist only of lowercase English letters. The size of each input file will be less than 5MB.

Output

For each test case, output “Yes” if GZS can convert s to t, otherwise output “No”.

Sample Input

4
a
b
cat
cats
do
do
apple
aapple

Sample Output

No
Yes
Yes
No

核心思想:

字符串s一定是字符串t的子序列,否则一定No。
因为选中的和增添的字符不能相同,我们要研究当增添的字符是连续且相同的怎么办?
我们将s中的字符和t中可匹配的字符中位置最靠后的匹配,然后采用如下方案

假设t匹配到位置j,令c=t[j+1],(c可能要被增添不止一次!)
第一步:将此部分需要被增添的所有字符c先插入(此步增添时,增添和选中的一定不同,因为如果它俩是相同的,那么他俩就匹配了,也就不用插入了)。
第二步:将其他字符逆序插入(此步增添时,由于有第一步的若干个字符c做前驱,也不会产生矛盾)。

这样,后面的字符在增添时都不矛盾了。现在,我们要找第一个被选中的位置,判断它和后面增添的字符是否相同就可以了!
分析增添方案是为了化简题目,我们的代码不用模拟增添的过程!!!

什么样的位置可以做第一个位置呢?
要求一:此位置之前s和t必须相同,因为第一个位置之前不能增添,否则就不能称之为第一个位置了!
要求二:此位置之后,s和t又能匹配成功,即s是t的子序列。怎么知道s是不是t的子序列呢?双指针遍历两个字符串即可。
结合以上两个要求,我们用一个for循环顺序寻找两个字符串第一个不同字符的位置(那么在此位置之前,两字符串相同)。将两字符串匹配时就逆序进行。
详见代码!

代码如下:

#include<stdio.h>
#include<string.h>
const int N=1e5+20;
char s[N],t[N];
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%s%s",s,t);
		int k=0,flag=0,ls=strlen(s),lt=strlen(t);
		for(;k<ls&&s[k]==t[k];k++);//寻找s和t第一个不同的字符 
		for(int i=ls-1,j=lt-1;i>=0&&j>=i&&!flag;j--)//i指示s,j指示t 
		{
			if(i<k&&t[i]!=t[i+1]) flag=1;//判断位置i能否当作第一个被选中的位置 
			if(s[i]==t[j]) i--;//匹配成功i-- 
		}
		if(flag) printf("Yes\n");
		else printf("No\n");
	}
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值