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。
考试的时候一开始看错题,发现的时候已经1h+了(AFO flag*1)。
于是一鼓作气删掉了我的代码。。。
写了一发之后发现过了大小样例(开心*1)。
于是去开T2了(AFO flag*2)。
结果惊奇的发现在lemon上我的程序爆零了。。。
于是得出结论:我少讨论了两种情况。。。
希望NOIP不考字符串模拟吧(NOIP–AFO flag*1)
代码:
#include
#define N 300005
using namespace std;
int T,n,m,cnt1[N],cnt2[N];
char s[N],t[N],ss[N],tt[N];
bool is[N];
int main(){
freopen("string.in","r",stdin);
freopen("string.out","w",stdout);
scanf("%d",&T);
while(T--){
scanf("%s%s",s+1,t+1);
n=strlen(s+1),m=strlen(t+1);
int tot1=0,tot2=0;
for(int i=1;i<=n;++i){
int cnt=1;
bool zxy=false;
char tmp=s[i];
while(i!=n&&(s[i+1]=='*'||s[i+1]==tmp)){
++i;
if(s[i]=='*')zxy=true;
if(s[i]==tmp)++cnt;
}
cnt1[++tot1]=cnt,ss[tot1]=tmp,is[tot1]=zxy;
}
for(int i=1;i<=m;++i){
int cnt=1;
char tmp=t[i];
while(i!=m&&t[i+1]==tmp)++i,++cnt;
cnt2[++tot2]=cnt,tt[tot2]=tmp;
}
if(tot1!=tot2){puts("No");continue;}
bool f=true;
for(int i=1;i<=tot1;++i)if((ss[i]!=tt[i])||(cnt1[i]>cnt2[i])||(!is[i]&&(cnt1[i]!=cnt2[i]))){f=false;break;}
if(f)puts("Yes");
else puts("No");
}
return 0;
}