NOIP模拟 字符串string

【题目描述】

        给定两个字符串s,t,其中s只包含小写字母以及*,t只包含小写字母。你可以进行任意多次操作,每次选择s中的一个*,将它修改为任意多个(可以是0个)它的前一个字符,问能否将s修改为t。

【输入格式】

        第一行一个整数T表示数据组数。

        每组数据两行,第一行一个字符串s,第二行一个字符串t。

【输出格式】

        每组数据输出一行,如果能将s修改为t,输出Yes,否则输出No。

【输入样例】

2

a*

aaaa

a*

ab

【输出样例】

Yes

No

【备注】

数据规模:

对于20%的数据,|s|,|t|<=7。

对于60%的数据,|s|,|t|<=300。

对于100%的数据,T<=100,|s|,|t|<=30000。

对于20%的数据,可以发现多个*连在一起与1个*效果等价,所以只需枚举每个*将上一个字母复制了多少遍。

对于60%的数据,用f[i][j]表示s[1..i]能否变为t[1..t],如果s[i]不是*则f[i][j]=f[i-1][j-1],否则f[i][j]=max{f[i-1][k]},其中t[k+1]..t[j]=s[i-1],复杂度(T|s||t|)

对于100%的数据,用lens指向s,lent指向t,将每一段相同字母分离出来比较,如果s字符个数大于t字符个数,那么为非法情况,如果s少于t且s这段中无*,那么同样非法,其他情况均合法,复杂度(T|s|+|t|)

贴代码:

#include<bits/stdc++.h>
using namespace std;

char s[30001],t[30001];
int len1,len2,ids,idt;

bool cmp(char c)
{
	int cnts=0,cntt=0;
	bool flag=false;
	while(s[ids]==c||s[ids]=='*')
	{
	    if(s[ids]==c)
	      cnts++;
	    if(s[ids]=='*')
	      flag=true;
		ids++;
	}
	while(t[idt]==c)
	  idt++,cntt++;
	if(cnts>cntt)
	  return false;
	if(cnts<cntt&&!flag)
	  return false;
	return true;
}

int main()
{
	int q;
	scanf("%d",&q);
	while(q--)
	{
		scanf("%s",s);
		scanf("%s",t);
		len1=strlen(s),len2=strlen(t);
		ids=0,idt=0;
		char r;
		if(s[0]==t[0])
		  r=t[0];
		else
		{
			puts("No");
			continue;
		}
		bool flag=true,flag1=false;
		while(flag&&(ids<len1&&idt<len2))
		{
			flag=cmp(r);
			if(s[ids]==t[idt])
			  r=s[ids];
			else
			{
				puts("No");
				flag1=true;
				break;
			}
		}
		if(!flag1)
		{
			if(!flag)
			  puts("No");
			else
			  puts("Yes");
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/g21glf/article/details/81943871
今日推荐