三元数异或

91 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第27天,点击查看活动详情

题目描述

如果一个整数,其各个数位不包含 0,1,20,1,2 以外的数字,则称这个数为三元数。

例如,1022,11,21,20021022,11,21,2002 都是三元数。

给定一个可能很长的三元数 xx,其首位数字(最左边那位)保证为 22,其他位数字为 00 或 11 或 22。

我们规定,两个长度为 nn 的三元数 aa 和 bb 可以通过三元异或运算 ⊙⊙ 得到另一个长度为 nn 的三元数 cc。

设 ai,bi,ciai,bi,ci 分别表示 a,b,ca,b,c 的第 ii 位的数字,则 ci=(ai+bi)mod3ci=(ai+bi)mod3。

例如,10222 ⊙ 11021=2121010222 ⊙ 11021=21210。

你的任务是对于每个给定的 xx,求出可以满足 a ⊙ b=xa ⊙ b=x,并且 max(a,b)max(a,b) 尽可能小的 a,ba,b。

注意,a,ba,b 都必须是 nn 位三元数,且不含前导 00。

输入格式

第一行包含整数 TT,表示共有 TT 组测试数据。

每组数据第一行包含整数 nn,表示 xx 的长度。

第二行包含一个长度为 nn,首位为 22 的三元数 xx。

输出格式

每组数据输出占两行,分别包含数 aa 和数 bb。

如果答案不唯一,则输出任意合理答案均可。

数据范围

1≤T≤1041≤T≤104, 1≤n≤5×1041≤n≤5×104, 同一测试点所有 nn 的和不超过 5×1045×104。

输入样例:

4
5
22222
5
21211
1
2
9
220222021

输出样例:

11111
11111
11000
10211
1
1
110111011
110111010

思路

模拟+贪心

题目要求 max(a,b)max(a,b) 最小,所以我们希望能均匀分配时优先均匀分配。 对于 ci=0ci=0,必然有 ai=bi=0ai=bi=0 对于 ci=1ci=1 或 ci=2ci=2,分别可以使 (ai,bi)=(0,1)(ai,bi)=(0,1) 以及 (ai,bi)=(0,2)(ai,bi)=(0,2) ,但这样会导致两个数不等,由于我们需要 max(a,b)max(a,b) 尽可能小,所以我们在第一次不均匀分配时将较大的数分配给 aa,这样无论之后如何分配,都能保证 a>ba>b,所以 max(a,b)=amax(a,b)=a,为了使该值保持不变,此后我们每次遇到不均匀分配的情况,均将所有较大的数都分配给 bb 即可。 由于数可能较大,我们用字符串处理。

代码

#include <bits/stdc++.h>
using namespace std;
using ll = long long; 
​
int main() {
    int T = 1;
    cin >> T;
    while(T--) {
        int n;
        cin >> n;
        string a;
        cin >> a;
​
        string s = "", t = "";
        bool ok = false; // 记录是否出现了不均匀分配
​
        for(int i = 0; i < n; i++) {
            if(a[i] == '2') {
                if(ok) {
                    s += '0';
                    t += '2';
                } else {
                    s += '1';
                    t += '1';
                }
            } else if(a[i] == '1') {
                if(ok) {
                    s += '0';
                    t += '1';
                } else {
                    s += '1';
                    t += '0';
                    ok = true;
                }
            } else {
                s += '0';
                t += '0';
            }
        }
​
​
        cout << s << endl << t << endl;
​
    }
}