Codeforces Round #704 (Div. 2) D. Genius‘s Gambit 构造 + 细节

传送门

题意: a , b , k a,b,k a,b,k,要求用 a a a 0 0 0 b b b 1 1 1组成二进制 x x x y y y,并且 x − y x-y xy恰好有 k k k 1 1 1,并且 x x x y y y不含前导零

思路: 首先需要看到不含前导零,一开始没看见wa5了。让后一个很明显的构造,举个例子: a = 4 , b = 2 , k = 3 a=4,b=2,k=3 a=4,b=2,k=3那么可以构造 x = 10 ∣ 1000 x=10|1000 x=101000 y = 10 ∣ 0001 y=10|0001 y=100001,我把前后两部分划分开了,前面的是多出来的,我们看后面,显然可以用一个 1 1 1 k k k 0 0 0来构造出来答案。现在解决了 a < = k a<=k a<=k的情况,如果 a > k a>k a>k呢?因为我们 0 0 0的贡献考虑完了,我们可以尝试在 1000 1000 1000 0001 0001 0001中加入 1 1 1,可以发现在相同位置都加上 1 1 1可以使最终 1 1 1的个数 + 1 +1 +1。比如 10 ∣ 10 ∣ 11 ∣ 0 10|10|11|0 1010110 10 ∣ 00 ∣ 11 ∣ 1 10|00|11|1 1000111,除去第一个竖杠,两个新竖杠之间的是我们在 x = 10 ∣ 1000 x=10|1000 x=101000 y = 10 ∣ 0001 y=10|0001 y=100001的基础上加上的,二者相减即可发现最终 1 1 1的个数多了 2 2 2。那么现在就解决了吗?我们还漏了一点就是 k = a + b k=a+b k=a+b的时候,这个时候是无解的,这个是比较容易看出来的。
让后就是构造完之后看看第一个数是否是 0 0 0即可。注意多出来的如果有 1 1 1一定要往开头放。
让后因为我的代码实现的缘故,需要特判一下 a = = 0 a==0 a==0 b = = 0 b==0 b==0

//#pragma GCC optimize(2)
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<cctype>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<sstream>
#include<ctime>
#include<cstdlib>
#define X first
#define Y second
#define L (u<<1)
#define R (u<<1|1)
#define pb push_back
#define mk make_pair
#define Mid (tr[u].l+tr[u].r>>1)
#define Len(u) (tr[u].r-tr[u].l+1)
#define random(a,b) ((a)+rand()%((b)-(a)+1))
#define db puts("---")
using namespace std;

//void rd_cre() { freopen("d://dp//data.txt","w",stdout); srand(time(NULL)); }
//void rd_ac() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//AC.txt","w",stdout); }
//void rd_wa() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//WA.txt","w",stdout); }

typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;

const int N=1000010,mod=1e9+7,INF=0x3f3f3f3f;
const double eps=1e-6;

int a,b,k;

bool check()
{
    if(!a)
    {
        if(k) return false;
        puts("YES");
        for(int i=1;i<=b;i++) printf("1"); puts("");
        for(int i=1;i<=b;i++) printf("1"); puts("");
        return true;
    }
    if(!b&&k) return false;
    if(!b&&!k)
    {
        puts("YES");
        for(int i=1;i<=a;i++) printf("0"); puts("");
        for(int i=1;i<=a;i++) printf("0"); puts("");
        return true;
    }
    if(k<=a)
    {
        if(b==1&&k!=0) return false;
        string x,y; b--; a-=k;
        for(int i=1;i<=k;i++) x+='0'; x+='1';
        y+='1'; for(int i=1;i<=k;i++) y+='0';
        for(int i=1;i<=b;i++) x+='1',y+='1';
        reverse(x.begin(),x.end());
        reverse(y.begin(),y.end());
        for(int i=1;i<=a;i++) x+='0',y+='0';
        if(y[0]=='0') return false;
        puts("YES");
        cout<<x<<endl;
        cout<<y<<endl;
        return true;
    }
    else if(k==a+b) return false;
    else
    {
        if(b==1&&k!=0) return false;
        string x,y; b--; b-=k-a;
        if(!b) return false;
        x+='0'; y+='1';
        for(int i=1;i<=k-a;i++) x+='1',y+='1';
        for(int i=1;i<=a-1;i++) x+='0',y+='0';
        x+='1'; y+='0';
        for(int i=1;i<=b;i++) x+='1',y+='1';
        reverse(x.begin(),x.end());
        reverse(y.begin(),y.end());
        if(y[0]=='0')  return false;
        puts("YES");
        cout<<x<<endl;
        cout<<y<<endl;
        return true;
    }
}

int main()
{
//	ios::sync_with_stdio(false);
//	cin.tie(0);

    scanf("%d%d%d",&a,&b,&k);
    if(!check()) puts("NO");



	return 0;
}
/*

*/



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值