题目:
题意:
给出两个字符串,第一个串中有若干个 ′ ∗ ′ '*' ′∗′,这个字符可以表示成任意个前一个的字符
问第一个字符串能否变为第二个字符串
分析:
我们考虑将相邻的相同字符缩成一个块,在计算答案的时候就看块所代表的字符是否相同,大小是否相同
对于特殊的 ′ ∗ ′ '*' ′∗′,我们在缩块的时候可以直接忽略,对于所属的字符块打上一个 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;
}