1. 程式人生 > >Codeforces Round #545 (Div. 2)D(KMP,最長公共前後綴,貪心)

Codeforces Round #545 (Div. 2)D(KMP,最長公共前後綴,貪心)

strlen lse ros ++ clu str 足夠 force 標記

#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‘);
}

Codeforces Round #545 (Div. 2)D(KMP,最長公共前後綴,貪心)