2018.08.22 NOIP模拟 string(模拟)

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;
}

转载于:https://www.cnblogs.com/ldxcaicai/p/9738354.html

你可能感兴趣的:(2018.08.22 NOIP模拟 string(模拟))