原题链接:https://codeforces.ml/contest/1492/problem/D
题意
给出a个0和b个1组成两个二进制串x、y,要求满足:
- x - y 的二进制中1的个数为k个
- x大于y
- x和y都没有前导零
分析
这题有很多特判的细节,提前说一下。
- 因为是x大于y,因此我们直接把x串设置成111…1000…的形式
- 当a为0或b为1时,k只要不是0就输出NO
- 当k=0时,直接输出YES
然后就是构造的技巧,先假设一个串110000。
我们先让x和y都设置为110000,然后将最右边的1往右边移,发现每移动一格,答案增加1,这时最大值为a,所以当k小于等于a时答案就出来了。
那么当k大于a怎么办,我们可以把剩余的点接着移,例如串111100。
先把y变成111001,然后再把剩余的最右边的1往右移动一格变成1101001,发现答案又增加1;再移一格变成1011001,这时就不能再移了,因为不能有前导零,这时就达到了最大的答案,只有最左端的两个值为0,其余为1。
拓展一下,a个0和b个1最多可以得到的k是a+b-2,这样就解出无解的情况了。
Code
#include <bits/stdc++.h>
using namespace std;
//#define ACM_LOCAL
#define fi first
#define se second
#define il inline
#define re register
typedef long long ll;
typedef pair<int, int> PII;
typedef unsigned long long ull;
const int N = 5e5 + 10;
const int M = 1e6 + 10;
const int INF = 1e9 + 5;
const double eps = 1e-5;
const int MOD = 998244353;
void solve() {
int a, b, k; cin >> a >> b >> k;
if (k == 0) {
cout << "YES" << endl;
for (int i = 1; i <= a+b; i++) {
if (i <= b) cout << 1;
else cout << 0;
}
cout << endl;
for (int i = 1; i <= a+b; i++) {
if (i <= b) cout << 1;
else cout << 0;
}
cout << endl;
} else if (k > a + b - 2) cout << "No" << endl;
else if (b == 1 && k != 0) cout << "NO" << endl;
else if (a == 0 && k != 0) cout << "NO" << endl;
else {
cout << "YES" << endl;
if (a >= k) {
for (int i = 1; i <= a+b; i++) {
if (i <= b) cout << 1;
else cout << 0;
}
cout << endl;
for (int i = 1; i <= a+b; i++) {
if (i <= b-1) cout << 1;
else if (i < b+k) cout << 0;
else if (i == b+k) cout << 1;
else cout << 0;
}
} else {
for (int i = 1; i <= a+b; i++) {
if (i <= b) cout << 1;
else cout << 0;
}
cout << endl;
int left = k-a;
for (int i = 1; i <= a+b; i++) {
if (i <= b-1-left) cout << 1;
else if (i == b-left) cout << 0;
else if (i <= b) cout << 1;
else if (i <= a+b-1) cout << 0;
else cout << 1;
}
}
cout << endl;
}
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
#ifdef ACM_LOCAL
freopen("input", "r", stdin);
freopen("output", "w", stdout);
#endif
solve();
}