Codeforces 1492D - Genius's Gambit (构造)

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\)


否则,观察样例,自己多写几个例子,可以发现这个规律

pic

中间位对应都相同时,计算减法可以直接当作\(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\)

答案总体可以分成以下三个部分(其中后两个部分位置可以随意调换)

pic2




程序

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

https://blog.csdn.net/qq_36394234/article/details/113999097

posted @ 2021-02-23 19:05  StelaYuri  阅读(329)  评论(0编辑  收藏  举报