http://codeforces.com/problemset/problem/1137/B
题意:
给定两个01串s和t。s中的字符可以重排。求使得t在s中出现的次数最多的重排
意思是t中的字母可以不连续但相对位置一定不变就叫做t在s中出现。
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<vector>
#include<cmath>
#include<string>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
char s[500001],t[500001];
int next_s[500001];
char stack[500001];
void getnext(){
ll len=strlen(t);
int i=0,j=-1;
next_s[0]=-1;
while(i<len){
//下面的逻辑或千万别误写为逻辑与
if(j==-1||t[i]==t[j])next_s[++i]=++j;
else j=next_s[j];
}
}
int main(){
scanf("%s%s",s,t);
getnext();//一开始忘调用了,哈哈
ll len1=strlen(s);
ll len2=strlen(t);
int cnt0=0,cnt1=0;
//计算出总的0和1的个数
for(int i=0;i<len1;i++){
if(s[i]=='0')cnt0++;
else cnt1++;
}
int top=0;
//先将字符串t存到数组中
for(int i=0;i<len2;i++){
stack[top++]=t[i];
if(t[i]=='0')cnt0--;//抵消0和1
else cnt1--;
}
if(cnt1<0||cnt0<0){//如果这样就没有一个方案可以
cout<<s<<endl;
return 0;
}
int p=next_s[len2];//开始找所有的字符串r
for(int i=p;;){
if(i==len2){//找到一个r再找下一个r
i=p;
}
if(t[i]=='0'&&cnt0){
cnt0--;stack[top++]=t[i++];
}
else if(t[i]=='1'&&cnt1){
cnt1--;stack[top++]=t[i++];
}
else break;//找不到了就退出来
}
//打印t+r+r+r+...
for(int i=0;i<top;i++){
cout<<stack[i];
}
//打印剩余的无关元素
while(cnt0--){
cout<<0;
}
while(cnt1--){
cout<<1;
}
cout<<endl;
return 0;
}