Codeforces Round #704 (Div. 2) D. Genius's Gambit
題意
要求構造出兩個不包含前導0的二進制數字\(x,y\),滿足:
- \(x,y\)都具有\(a\)個\(0\)和\(b\)個\(1\)
- \(x-y\)具有\(k\)個\(1\)
限制
\(a\ge 0\)
\(b\ge 1\)
\(0\le k\le a+b\le 2\cdot 10^5\)
思路
顯然的,由於要求\(x,y\)不包含前導\(0\),故兩數字最高位必定為\(1\)
特殊討論\(k=0\)時,根據上述約束,直接輸出兩個字符串即可
注意先輸出\(b\)個\(1\)再輸出\(a\)個\(0\)
否則,觀察樣例,自己多寫幾個例子,可以發現這個規律
中間位對應都相同時,計算減法可以直接當作\(X-X=0\)
那么假如這一段的長度為\(t\),減數最高位為\(1\),被減數最低位為\(1\),其余\(t-1\)個位置均為\(0\)
那做減法得到的結果即\(2^{t-1}-1\),其二進制則包含\(t-1\)個\(1\)
那么只要\(k\neq 0\),就需要保證至少要有\(2\)個\(1\)與\(1\)個\(0\),且\(k\le a+b-2\)
答案總體可以分成以下三個部分(其中后兩個部分位置可以隨意調換)
程序
#include<bits/stdc++.h>
using namespace std;
void solve()
{
int a,b,k;
cin>>a>>b>>k;
if(k==0)
{
cout<<"Yes\n";
for(int i=1;i<=b;i++) cout<<1;
for(int i=1;i<=a;i++) cout<<0;
cout<<'\n';
for(int i=1;i<=b;i++) cout<<1;
for(int i=1;i<=a;i++) cout<<0;
cout<<'\n';
return;
}
if(a<1||b<2||k>a+b-2)
{
cout<<"No\n";
return;
}
string x="1",y="1";
b--;
x+='1',y+='0';
a--,b--;
for(int i=1;i<k;i++)
{
if(a>0)
{
a--;
x+='0',y+='0';
}
else if(b>0)
{
b--;
x+='1',y+='1';
}
}
x+='0',y+='1';
while(a--)
x+='0',y+='0';
while(b--)
x+='1',y+='1';
cout<<"Yes\n"<<x<<'\n'<<y<<'\n';
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
solve();
return 0;
}