3764 三元数异或(贪心)

1. 问题描述:

如果一个整数,其各个数位不包含 0,1,2 以外的数字,则称这个数为三元数。例如,1022,11,21,2002 都是三元数。给定一个可能很长的三元数 x,其首位数字(最左边那位)保证为 2,其他位数字为 0 或 1 或 2。我们规定,两个长度为 n 的三元数 a 和 b 可以通过三元异或运算 ⊙ 得到另一个长度为 n 的三元数 c。设 ai,bi,ci 分别表示 a,b,c 的第 i 位的数字,则 ci = (ai + bi) mod 3。
例如,10222 ⊙ 11021 = 21210。你的任务是对于每个给定的 x,求出可以满足 a ⊙ b = x,并且 max(a,b) 尽可能小的 a,b。注意,a,b 都必须是 n 位三元数,且不含前导 0。

输入格式

第一行包含整数 T,表示共有 T 组测试数据。每组数据第一行包含整数 n,表示 x 的长度。第二行包含一个长度为 n,首位为 2 的三元数 x。

输出格式

每组数据输出占两行,分别包含数 a 和数 b。如果答案不唯一,则输出任意合理答案均可。

数据范围

1 ≤ T ≤ 10 ^ 4,
1 ≤ n ≤ 5 × 10 ^ 4,
同一测试点所有 n 的和不超过 5×104。

输入样例:

4
5
22222
5
21211
1
2
9
220222021

输出样例:

11111
11111
11000
10211
1
1
110111011
110111010
来源:https://www.acwing.com/problem/content/description/3767/

2. 思路分析:

分析题目可以知道涉及到的是异或运算,异或运算又被称为不进位的加法,可以从二元扩展到三元,现已知一个x,我们需要使得a ⊙ b = x并且使得max{a,b}最小求解满足条件的a,b,因为异或运算中每一位都是独立的所以位与位之间没有影响,所以我们可以逐位进行考虑,令a <= b(反过来也是一样的两者是对称的),分x[i] = 0,1,2进行考虑,要想使得a越小那么应该使得最高位越小(不用考虑a的某一位的情况因为填2的时候会比其余两种情况都要大):

3. 代码如下:

class Solution:
    def process(self):
        T = int(input())
        for i in range(T):
            n = int(input())
            s = input()
            a = b = ""
            # flag表示当前a == b还是a > b方便后面确定填什么
            flag = 0
            for j in range(n):
                c = s[j]
                if c == "0":
                    a += "0"
                    b += "0"
                elif c == "1":
                    if flag:
                        a += "0"
                        b += "1"
                    else:
                        a += "1"
                        b += "0"
                        # 更新标记
                        flag = 1
                elif c == "2":
                    if flag:
                        a += "0"
                        b += "2"
                    else:
                        a += "1"
                        b += "1"
            print(a)
            print(b)


if __name__ == '__main__':
    Solution().process()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值