版权声明:转载请声明出处,谢谢配合。 https://blog.csdn.net/zxyoi_dreamer/article/details/81942776
【描述】
给定两个字符串 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。
解析:
今日份的签到题。
做法多种。我的选择是把 和 分别拆开,把字符相同的一段存进一个节点, 跟着它前面的节点。
注意可能有多个
连在一起的情况,
还可能有
前后是同一字符的情况,
还可能有开头为
的非法情况。
都特殊处理一下就好了。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define pc putchar
#define gc getchar
#define cs const
#define st static
inline
int getint(){
int num;
char c;
for(c=gc();!isdigit(c);c=gc());
for(num=0;isdigit(c);c=gc())num=(num<<1)+(num<<3)+(c^48);
return num;
}
struct node{
bool unlimit;
char c;
int num;
node (bool _limit,char _c,int _num):
unlimit(_limit),c(_c),num(_num){}
};
int T;
char s[30005],t[30005];
int sl,tl;
int spos,tpos;
int main(){
// freopen("string.in","r",stdin);
// freopen("string.out","w",stdout);
T=getint();
while(T--){
scanf("%s",s);
scanf("%s",t);
if(s[0]=='*'){
puts("No");
continue;
}
sl=strlen(s);
tl=strlen(t);
vector<node> sn;
vector<node> tn;
int cnt=1;
char pre=s[0];
bool flag=0;
for(int re i=1;i<sl;++i){
if(s[i]=='*'){
flag=true;
continue;
}
if(s[i]!=pre){
sn.push_back(node(flag,pre,cnt));
cnt=1;
pre=s[i];
flag=0;
continue;
}
++cnt;
}
sn.push_back(node(flag,pre,cnt));
cnt=1;
pre=t[0];
for(int re i=1;i<tl;++i){
if(t[i]!=pre){
tn.push_back(node(0,pre,cnt));
pre=t[i];
cnt=1;
continue;
}
++cnt;
}
tn.push_back(node(0,pre,cnt));
if(sn.size()!=tn.size()){
puts("No");
continue;
}
flag=1;
for(int re i=0;i<sn.size();++i){
node &ss=sn[i];
node &tt=tn[i];
if(ss.c!=tt.c){
flag=false;
break;
}
if(ss.unlimit){
if(ss.num>tt.num){
flag=false;
break;
}
continue;
}
if(ss.num!=tt.num){
flag=false;
break;
}
}
if(flag)puts("Yes");
else puts("No");
}
return 0;
}