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
*/
希望我们都有一个光明的未来