当前位置:   article > 正文

蓝桥-异或数列 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

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

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

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

  1. for i in range(1,len(rnt)):
  2. Get_Bit((rnt[i]))
  3. flag^=rnt[i]
  4. if flag==0:
  5. print(0)
  6. continue

全部代码如下: 

  1. n=int(input())
  2. def Get_Bit(k):
  3. global arr
  4. n=0
  5. while(k>=1):#按位与运算,求得每一位的1数量
  6. arr[n]+=k&1
  7. k>>=1
  8. n+=1
  9. for i in range(n):
  10. arr=[0 for i in range(22)]
  11. rnt=list(map(int,input().split()))
  12. flag=0
  13. for i in range(1,len(rnt)):
  14. Get_Bit((rnt[i]))
  15. flag^=rnt[i]
  16. if flag==0:
  17. print(0)
  18. continue
  19. for i in range(21,-1,-1):#三种情况,其实只需要把整个1和0给想象成一个数列,a和b都是想获得最后胜利,即为了最后一次获得1(通过0来改变运算顺序),如果0为偶数,1为奇数,则无论如何b都变不了,a胜,反正亦然
  20. if arr[i]%2 == 0:
  21. continue
  22. elif (arr[i]%2 and (len(rnt)-1-arr[i]) %2 ==0 ) or arr[i]==1 :
  23. print(1)
  24. break
  25. else:
  26. print(-1)
  27. break

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

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

input=sys.stdin.readline
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/560705
推荐阅读
相关标签
  

闽ICP备14008679号