蓝桥杯 异或数列 python组

题目描述

Alice 和 Bob 正在玩一个异或数列的游戏。初始时,Alice 和 Bob 分别有一个整数 a 和 b,初始值均为 0。

有一个给定的长度为 n​​ 的公共数列 X1​,X2​,⋯,Xn​​。Alice 和 Bob 轮流操作,Alice 先手,每步可以在以下两种选项中选一种:

选项 1:从数列中选一个 Xi​​​ 给 Alice 的数异或上,或者说令 a​​ 变为 a⊕Xi​​​。(其中 ⊕​​ 表示按位异或)

选项 2:从数列中选一个 Xi​​​ 给 Bob 的数异或上,或者说令 b​​ 变为 b⊕Xi​​​。

每个数 Xi​​ 都只能用一次,当所有 Xi​ 均被使用后(n​​ 轮后)游戏结束。游戏结束时,拥有的数比较大的一方获胜,如果双方数值相同,即为平手。 现在双方都足够聪明,都采用最优策略,请问谁能获胜?

输入描述

每个评测用例包含多组询问。询问之间彼此独立。

输入的第一行包含一个整数 T,表示询问数。

接下来 T​ 行每行包含一组询问。其中第 i​ 行的第一个整数 ni​​ 表示数列长度,随后 ni​​ 个整数 X1​,X2​,⋯,Xni​​ 表示数列中的每个数。

输出描述

输出 T​​ 行,依次对应每组询问的答案。 每行包含一个整数 1​​、0​ 或−1 分别表示 Alice 胜、平局或败。

解答:Alice赢的先决条件是什么,是这组讯问中的最大数的最高位为真的数只有一个,或有奇数个但最高位为假的有偶数个,这是Alice胜的条件。而平局只有这组询问中的所有值异或结果为0的时候才会平局。其他条件则是Bob胜。

t = int(input())

def check(lst):

  result = 0

  max1 = 0

  for i in lst[1:]:

    result ^= i        #将这组询问的所有值进行异或

    max1 = max(max1,i)        #max1为这组询问的最大值

  if result==0:        #如果异或的结果为0,则说明平局

    print(0)

    return

  high = 1        #表示最大值的最高位

  while high<max1:        

    high = high<<1        #将high的数量级提升到最大值的数量级,简单地说,就是high的值只有最高位为1,进行异或时,只有另一个数和high的最高位值相同结果才为真,否,则为假

  while high>0:

    temp = 0

    for i in lst[1:]:

      if i&high != 0:        #计算最高位和high相同的数字的个数

        temp+=1

    if temp==1:        #如果只有一个最高位与high相同,则Alice胜

      print(1)

      return

    if temp%2==1:#最高位与high相同的值的个数为奇数且不为1

      if lst[0]%2==1:#如果最高位与high不同的个数为偶数个,则Bob是拿最后一个数的人,则Bob输

        print(1)

        return

      else:#如果最高位与high不同的个数为奇数个,则Alice是拿最后一个数的人,则Alice输

        print(-1)

        return

    else:

      high = high>>1#表示最高位有偶数个,即无法判断胜负,则依次递减到下一个高位,继续判断


 

for i in range(t):

  lst = list(map(int,input().split()))

  check(lst)        #把每一组询问的值带进check函数进行计算胜负

 

 

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

缱绻命运

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值