蓝桥-异或数列 python

异或:两个数相同为0 不同为1  例如 1xor1=0 0xor0=0 0xor1=1 1xor0=1 

 即0碰到任何数都不改变,1碰到1会为0、碰到0不变

思路:

把取的数看成二进制数,从最大位到最小位进行考虑

下面一位位进行分析:

1.分析可知,如果在这一位上面 有偶数个1,则不管怎么样都是平局,因为a取了1之后b总有办法让其变平,而a无可奈何。此时a,b取1个数一定相等(同为奇或同为偶),则一定平局。

2.如果这个位上面 只有1个1,则先手胜

3.如果这个位上面 有奇数个1

基于:一个奇数只能拆分成两个奇偶性不同的非负整数,当前这一位一定能分出胜负。

则问题转换为,谁获得最后一个1,谁取得胜利(前面拿到的1总会互相抵消)。此时0的作用就是相当于让自己轮空,即先后手交换。将0和1想象为一个序列。

(1)如果是偶数个0的话,相当于互相抵消,a和b都无法通过0来让自己轮空(对方取了0之后,先后手交换,你必须也取0来抵消对方取0造成的影响),则此时先手胜。

(2)如果是奇数个0的话,后手能通过0来使得自己轮空,且先手抵消不了这种影响总能成功改变先后手顺序。

例如111 0 这个序列 a取0 b变成先手,a取1 b取0 a只能继续取1 此时b变成先手。 111000也是类似的,a取0b取0 ,若a继续取0,则b先手,若a取1,则转换为上面分析的情况。a取1,则b通过0来交换先后手顺序,且由于0还有两个,a逆转不了这种影响。可知在奇数0情况下,后手无论如何都能改变先后手顺序,获得胜利。

1.获得每一位的1数量num,0的数量就是n-num

def Get_Bit(k):
    global arr
    n=0
    while(k>=1):#按位与运算,求得每一位的1数量
        arr[n]+=k&1
        k>>=1
        n+=1

2. 对所有数进行异或运算,若最终为0。由异或的性质(结合律,交换律)可知:

将所有数任意划分为两个非空集合,这两个集合中的异或和相等,ab初始值为0,那么最终异或的结果肯定也是相等的。

    for i in range(1,len(rnt)):
        Get_Bit((rnt[i]))
        flag^=rnt[i] 
    if flag==0:
        print(0)
        continue

全部代码如下: 

n=int(input())

def Get_Bit(k):
    global arr
    n=0
    while(k>=1):#按位与运算,求得每一位的1数量
        arr[n]+=k&1
        k>>=1
        n+=1

for i in range(n):
    arr=[0 for i in range(22)]
    rnt=list(map(int,input().split()))
    flag=0
    for i in range(1,len(rnt)):
        Get_Bit((rnt[i]))
        flag^=rnt[i] 
    if flag==0:
        print(0)
        continue
    for i in range(21,-1,-1):#三种情况,其实只需要把整个1和0给想象成一个数列,a和b都是想获得最后胜利,即为了最后一次获得1(通过0来改变运算顺序),如果0为偶数,1为奇数,则无论如何b都变不了,a胜,反正亦然
        if arr[i]%2 == 0:
            continue
        elif (arr[i]%2 and (len(rnt)-1-arr[i]) %2 ==0 ) or arr[i]==1 :
            print(1)
            break
        else:
            print(-1)
            break

 图源:试题 历届真题 异或数列【第十二届】【省赛】【A组】-CSDN博客

对于输入较大的可加入:加速读取

input=sys.stdin.readline
  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值