YbtOJ NOIP2020 模拟赛 B 组 Day3 B.字串修改【字符串】


题目:

传送门


题意:

给出两个字符串,第一个串中有若干个 ′ ∗ ′ '*' ,这个字符可以表示成任意个前一个的字符
问第一个字符串能否变为第二个字符串


分析:

我们考虑将相邻的相同字符缩成一个块,在计算答案的时候就看块所代表的字符是否相同,大小是否相同
对于特殊的 ′ ∗ ′ '*' ,我们在缩块的时候可以直接忽略,对于所属的字符块打上一个 m a r k mark mark,在检测答案的时候就只需保证其大小是 ⩽ \leqslant 第二个串对应的块的大小就好了


代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<queue>
#define LL long long
using namespace std;
inline LL read()
{
    
    
	LL s=0,f=1; char c=getchar();
	while(c<'0'||c>'9') {
    
    if(c=='-') f=-1;c=getchar();}
	while(c>='0'&&c<='9') {
    
    s=s*10+c-'0';c=getchar();}
	return s*f;
}
char s[30005],z[30005];
struct zf{
    
    
	int l,tf,step;char c;
}a[30005],b[30005];
int main()
{
    
    
	//freopen("strinq.in","r",stdin);
	//freopen("strinq.out","w",stdout);
	int t=read();
	while(t--)
	{
    
    
		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
		scanf("%s",&s); scanf("%s",&z);
		int ls=strlen(s),lz=strlen(z);
		int la=0,lb=0;
		for(int i=0;i<ls;i++) 
		{
    
    
			a[++la].c=s[i];a[la].l=1;
			while(s[i+1]==s[i]) i++,a[la].l++;
			if(s[i+1]=='*') {
    
    a[la].tf=1;i++;while(s[i]=='*') i++;}
			i-=a[la].tf;
		}
		for(int i=0;i<lz;i++)
		{
    
    
			b[++lb].c=z[i];b[lb].l=1;
			while(z[i+1]==z[i]) i++,b[lb].l++;
		}
		int cnt=0;
		for(int i=1;i<=la;i++) 
		{
    
    
			a[i].step=1;
			if(a[i].c!=a[i+1].c) continue;
			int k=i;
			while(a[i].c==a[i+1].c)
			{
    
    
				cnt++;
				a[k].step++;
				a[k].l+=a[i+1].l;
				a[k].tf=a[k].tf|a[i+1].tf;
				i++;
			}
		}
		if(la-cnt!=lb) {
    
    printf("No\n");continue;}
		int tt=0;
		for(int i=1,j=1;i<=la;i+=a[i].step,j++)
		{
    
    
			if(!a[i].tf) if(a[i].l!=b[j].l) {
    
    tt=1;break;}
			if(a[i].tf) if(a[i].l>b[j].l) {
    
    tt=1;break;}
 		}
		if(!tt) printf("Yes\n");
		else printf("No\n");
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_35786326/article/details/109058560