C 小红的01串(三)
首先考虑 的情况。
- 如果
,那么
中也得有一个为
,否则就输出
- 如果
,那么需要对
分类讨论
- 若
,那么
的理论最大值是
,如果超出这个范围就是
- 若
,那么
的理论最大值是
,如果超出这个范围就是
- 若
接下来考虑构造。通过刚刚判断 的过程中可以看出,我们可以先通过
这样的方式凑出
来,多出来的
或者
找某个地方一起***去即可。
如果直接写就会有一些问题:我们不知道是 开始构造还是
开始,需要写多个if,感觉很麻烦。
所以我们可以把这种操作封装成一个函数,具体看代码。
#include <bits/stdc++.h>
using namespace std;
int k;
void sort_01(int a, int b, int n1, int n2) {
// 其中n1,n2一个为0一个为1,表示我们要填的数
// 表示当前有a个n1和b个n2要填,其中我们想拿n1填第一个数
int numa = k / 2 + 1; // 要填numa个n1
int numb = (k + 1) / 2; // 要填numb个n2
for (int i = 1; i <= a - numa; i ++ ) cout << n1; // 先将多余的n1输出
cout << n1; // 输出主体部分中第一个n1
if (k & 1) {
// 如果是k是奇数,那么一定是n1开头n2结束,所以可以放心的把多余的n2放到尾部
for (int i = 1; i <= k; i ++ ) {
// 将n2和n1交替输出
if (i & 1) cout << n2;
else cout << n1;
}
// 输出多余的n2
for (int i = 1; i <= b - numb; i ++ ) cout << n2;
} else {
// 如果k是偶数,说明是n1开头n1结束,不能把多余的n2放到尾部
// 可以先不用输出最后一个n1
for (int i = 1; i < k; i ++ ) {
if (i & 1) cout << n2;
else cout << n1;
}
// 在输出最后一个n1之前先把多余的n2输出
for (int i = 1; i <= b - numb; i ++ ) cout << n2;
// 再输出最后一个n1
cout << n1;
}
cout << endl;
}
void solve() {
int a, b;
cin >> a >> b >> k;
if (k == 0) {
// k=0的特判
if (a != 0 && b != 0) cout << -1 << endl;
else {
for (int i = 1; i <= a; i ++ ) cout << 0;
for (int i = 1; i <= b; i ++ ) cout << 1;
cout << endl;
}
} else {
if (a == b && k > a + b - 1) {
cout << -1 << endl;
return ;
}
if (k > 2 * min(a, b)) cout << -1 << endl;
else {
// 如果0多,就先填0,否则先填1
if (a >= b) sort_01(a, b, 0, 1);
else sort_01(b, a, 1, 0);
}
}
}
int main() {
int T = 1;
cin >> T;
while (T -- )
solve();
return 0;
}