Codeforces Round #545 (Div. 2)D(KMP,最长公共前后缀,贪心)

#include<bits/stdc++.h>
using namespace std;
const int N=1000007;
char s1[N],s2[N];
int len1,len2;
int nex[N];
int cnt1[7],cnt2[7];
int main(){
    scanf("%s %s",s1+1,s2+1);
    len1=strlen(s1+1);
    len2=strlen(s2+1);
    for(int i=1;i<=len1;i++)
        cnt1[s1[i]-'0']++;
    for(int i=1;i<=len2;i++)
        cnt2[s2[i]-'0']++;
    if(cnt1[1]>=cnt2[1]&&cnt1[0]>=cnt2[0]){//如果个数足够先输出s2
     for(int i=1;i<=len2;i++)
            putchar(s2[i]);
     cnt1[0]-=cnt2[0];
     cnt1[1]-=cnt2[1];
    }
    for(int i=2,j=0;i<=len2;i++){//kmp寻找最长公共前后缀
        while(s2[i]!=s2[j+1]&&j)//这一位不相等就把模式串返回到标记
            j=nex[j];
        if(s2[i]==s2[j+1])//相等就让模式串位置前进,模式串可能为空此时不需要使模式串标记前进,因为模式串里面没有能和主串相等的字符
            j++;
        nex[i]=j;//记录标记,以便以后返回
    }
    while(cnt1[1]&&cnt1[0]){
     int flag=0;
     for(int i=nex[len2]+1;i<=len2;i++){//贪心地从最长公共前后缀的下一位开始输出
      if(cnt1[s2[i]-'0']){
       putchar(s2[i]);
       cnt1[s2[i]-'0']--;
      }
      else{
       flag=1;
                break;
      }
     }
     if(flag)
            break;
    }
    for(int i=1;i<=cnt1[0];i++)//输出剩余的0或1
        putchar('0');
    for(int i=1;i<=cnt1[1];i++)//输出剩余的0或1
        putchar('1');
}

猜你喜欢

转载自www.cnblogs.com/ldudxy/p/10508226.html