首页 > 其他 > 详细

CF708B

时间:2020-09-15 18:08:00      阅读:41      评论:0      收藏:0      [点我收藏+]

构造好题
先排除特殊情况(全0,全1,只有一个字符)
显然可以通过 \(a_{00}\)\(a_{11}\) 得到零和一的个数,然后我们可以判断无解(\(cnt_0 * cnt_1 \ne a_{01} + a_{10}\)
假定1全在前面,0全在后面,然后直接构造(能把a_{10}消掉就消掉,不能的考虑在后面的0中间加个1,最后把剩下的1填到后面,因为此时保证有解,所以一定是对的。)

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>

using namespace std;

typedef long long ll;
const ll MAXN = 1e6+10;

ll Z, Y, a[4], ans[MAXN];

int main() {
    for (ll i = 0; i < 4; i++) {
        scanf("%lld", a+i);
    }
    ll Z = floor(sqrt(2 * a[0])) + 1;
    ll Y = floor(sqrt(2 * a[3])) + 1;
    if (2 * a[0] != (Z-1) * Z || 2 * a[3] != (Y - 1) * Y) {
		puts("Impossible");
    	return 0;
	}
	if (a[0] + a[1] + a[2] + a[3] == 0) {
		puts("0");
		return 0;	
	}
	if (a[0] + a[1] + a[2] == 0) {
		for (ll i = 1; i <= Y; i++) {
			printf("%lld", 1LL);
		}
		puts("");
		return 0;
	}
	if (a[1] + a[2] + a[3] == 0) {
		for (ll i = 1; i <= Z; i++) {
			printf("%lld", 0LL);	
		}
		puts("");
		return 0;
	}
    if (Y * Z != a[1] + a[2]) {
        puts("Impossible");
        return 0;
    }
    ll a2 = a[2], now = 0;
    while (a2) {
    	if (a2 > Z) {
    		ans[++now] = 1;
    		a2 -= Z;
    	} else {
    		now++;
    		ans[now + Z - a2] = 1;
			a2 = 0;	
    	}
    }
    for (ll i = 1; i <= Y - now; i++) ans[Y + Z - i + 1] = 1;
    for (ll i = 1; i <= Y + Z; i++) {
        printf("%lld", ans[i]);
    }
    return 0;
}

/*
3 6 3 3
*/

CF708B

原文:https://www.cnblogs.com/Gensokyo-Alice/p/13674295.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!