CF708B

构造好题
先排除特殊情况(全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
*/
posted @ 2020-09-15 17:34  Gensokyo_Alice  阅读(96)  评论(0编辑  收藏  举报