Codeforces Round #545 (Div. 2) D. Camp Schedule //kmp模板
http://codeforces.com/contest/1138/problem/D
重组01串s,使得包含尽量多的子串t
所以要求出字符串的前缀后后缀相同的最大长度。直接kmp
#include<bits/stdc++.h>
using namespace std;
#define mod 100000007
#define LL long long
char s[500005];
char t[500005];
int net[500005];
void GetNext(char* p,int net[])
{
int pLen = strlen(p);
net[0] = -1;
int k = -1;
int j = 0;
while (j < pLen)
{
if (k == -1 || p[j] == p[k])
{
++k;
++j;
net[j] = k;
}
else
{
k = net[k];
}
}
}
int main(){
scanf("%s%s",s,t);
GetNext(t,net);
int s0=0,s1=0,t0=0,t1=0;
int les=strlen(s),let=strlen(t);
for(int i=0;i<les;i++){
if(s[i]=='0')s0++;
else s1++;
}
for(int i=0;i<let;i++){
if(t[i]=='0')t0++;
else t1++;
}
int c=net[let];
if(s0>=t0&&s1>=t1){
s0-=t0;
s1-=t1;
cout<<t;
}
for(int i=0;i<c;i++){
if(t[i]=='0')t0--;
else t1--;
}
while(s0>=t0&&s1>=t1){
s0-=t0;
s1-=t1;
for(int i=c;i<let;i++){
cout<<t[i];
}
}
for(int i=1;i<=s0;i++)
cout<<0;
for(int i=1;i<=s1;i++)
cout<<1;
return 0;
}
https://blog.****.net/v_july_v/article/details/7041827#
void GetNext(char* p,int net[])
{
int pLen = strlen(p);
net[0] = -1;
int k = -1;
int j = 0;
while (j < pLen)
{
if (k == -1 || p[j] == p[k])
{
++k;
++j;
net[j] = k;
}
else
{
k = net[k];
}
}
}