[CF1508A] Binary Literature 的题解
我们定义 的数量大于等于 的字符串为 串,反之为 串。
那么显然有性质每一个字符串肯定都至少是这两种串中的一种,那么根据鸽巢原理在题目给定的 个串中,注定有 个串的类别是一样的。
不妨设这两个字符串分别是 ,他们都是 串,那么通过以下方式进行构造就一定可以构造出一个合法的方案:
-
维护两个指针 ,分别指向 两个数组中 的位置。
-
如果 ,那么输出 接着将 分别加 。
-
如果 ,那么输出 并将 加 。
-
如果 ,那么输出 并将 加 。
-
如果 或者 ,那么将不为 的指针之后的所有对应的字符输出。
容易理解 和 都是上面构造出的字符出的字串,接下来考虑证明使用上面的方法构造的字符串长度是否在 之内。
容易得到除 之外的操作都不会使输出的字符串比直接将两个字符串直接拼接起来段,所以真正的长度就是 。
因为在 中都不会有 输出,所以 的输出只在操作 中。因为 两串中至少有 个 ,所以因为 而执行的 的操作至少有 次,那么长度就一定小于 。
另外提供一个很短的代码实现:
#include<iostream>
using namespace std;
const int N=2e5+5;
int n,a0,a1,b0,b1,c0,c1,f;
char a[N],b[N],c[N];
void sswap(char a[],char b[]){
for(int i=1;i<=n*2;i++) swap(a[i],b[i]);
}
void solve(){
cin>>n,f=0;
cin>>a+1>>b+1>>c+1;
a0=a1=b0=b1=c0=c1=0;
for(int i=1;i<=n*2;i++){
a0+=a[i]=='0',a1+=a[i]=='1';
b0+=b[i]=='0',b1+=b[i]=='1';
c0+=c[i]=='0',c1+=c[i]=='1';
a[i]-=48,b[i]-=48,c[i]-=48;
}
if(a0!=n&&b0!=n){
if(c0==n) sswap(a,c),swap(a0,c0),swap(a1,c1);
else if(!((a0>=n)^(c0>=n))) sswap(b,c),swap(b0,c0),swap(b1,c1);
else if(!((b0>=n)^(c0>=n))) sswap(a,c),swap(a0,c0),swap(a1,c1);
}
if(a0<n||b0<n) f=1;
n<<=1;
int l=1,r=1;
while(l<=n&&r<=n){
if(a[l]==b[r]) cout<<(int)a[l++],r++;
else if(a[l]!=f) cout<<(int)a[l++];
else cout<<(int)b[r++];
}
for(int i=l;i<=n;i++) cout<<(int)a[i];
for(int i=r;i<=n;i++) cout<<(int)b[i];
cout<<'\n';
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;cin>>T;
while(T--) solve();
return 0;
}