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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM