赞
踩
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函数进行计算胜负
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。