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;
}