题解:
知识点很多,依次总结:
位运算:
1.左移/右移
针对二进制数位来说的
i<<=1#左移一位,向更高位 i>>=1#右移一位,向更低位
2.或操作| 与操作& 异或操作^
异或操作满足结合律、交换律和1^x=~x(即x翻转) 0^x=x的规律
3.求数的最高数位:
length=1 while length<=val: length<<=1
求得的length为0b100000...其中0的个数等于val化为二进制后的数位值,例如bin(15)=0b1111,为4位,那么length=0b10000
这有什么意义呢?
已知val和其对应的length,和另一个数字num length可用来判断num在数位length上的数字是0还是1!! if num&length==0: 为0 else: 为1
然后进行本题的分析:
首先明确一点:对于X1,X2,X3来说,Alice先选择X1,Bob还可以继续选择X1!!为什么说只能选择一次呢?那是针对一个人来说的,即Alice选择了一次X1,不能再选了,当任意一个人选完了X数组的所有值,游戏结束
1.平局的情况:a^b=0即a^b^X1^X2^X3.....^Xn=0,根据交换率和结合律以及异或的定义,这些数都相等,故X1^X2^...=0
2.X1^X2^...!=0时,因为最优策略,A赢的意思是:A能采取某种策略,不管B作何应对,A保证自己一定能赢;B赢的意思是:B能采取某种策略,不管A作何应对,B保证自己一定能赢,所以:
A赢的意思是:A能采取某种策略,不管B作何应对,A保证自己一定能赢;
B赢的意思是:B能采取某种策略,不管A作何应对,B保证自己一定能赢;
对于异或:0^X ——保持X ; 1^X——翻转X;
偶数次翻转将回到原来的状态,即与偶数个1异或将保持不变。最后两个结果数
A^B = a^b^sum
,其中sum为给定数列所有数的异或和,sum = X1^X2^...Xni
,所以如果是平局(即A = B),则A^B=0(即 sum = 0)。现在考虑sum != 0时,因为是按位异或,并且最后比较A和B两值的大小,所以要从二进制的最高位开始比较,如果最高位相等,比较次高位,以此往下比较,直到可以判断出结果。
用一个int型数组res[i]表示二进制的第i位上1的个数,如果某一位的res[i]为奇数,即该位上有奇数个1与a和b异或,比如有5个1,因为0不会改变状态,其(a,b)的状态转移过程一定是:(0,0)->翻转->平局->翻转->平局->翻转,也就是说在平局不管是(0,0)或(1,1)的基础上,Alice 和 Bob谁拥有最后一次翻转权(也就是最后一个1),谁就赢得游戏!
那怎么让最后一个1轮到自己身上?就要用到0了,因为0不会改变数的大小,但相当于让自己“轮空一次”。还是考虑上面5个1的情况:如果在最后一次翻转之前(不管在什么位置)插入偶数个0,则最后一次1的翻转权来到了先手 Alice,则先手胜出;如果在最后一次翻转之前(不管在什么位置)插入奇数个0,则最后一次1的翻转权来到了后手 Bob,则后手胜出。
因为Alice和Bob都“足够聪明”,面对奇数个1,Bob一定要去“ 抢0 ”,自己才有一线生机,而Alice也要以“ 抢0 ”来作应对,让最后一次翻转权回到自己手里,因为0的个数有限,最后决定胜负的就是0个数的奇偶性。
因此,如果某一位的res[i]为偶数,则游戏结果的这一位一定相等,考虑下一位 ;如果第i位上1的个数为 1,则一定是先手赢(输出:“1”);如果第i位上1的个数为大于1的奇数,0的个数为偶数,则先手赢(输出:“1”);如果第i位上1的个数为大于1的奇数,0的个数为奇数,则后手赢(输出:“-1”)。文章来源:https://www.toymoban.com/news/detail-403289.html
给出代码:文章来源地址https://www.toymoban.com/news/detail-403289.html
import os
import sys
# 请在此输入您的代码
T=int(input())
for i in range(T):
nums=list(map(int,input().split()))
li=nums[1:]
sumd=0
maxNum=0
for i in li:
sumd^=i
maxNum=max(maxNum,i)
if sumd==0:
print(0)
continue
length=1
while length<=maxNum:
length<<=1
while length>0:
zeros,ones=0,0
for i in li:
if i&length==0:
zeros+=1
else:
ones+=1
if ones%2!=0:
if onse==1:
print(1)
elif zeros%2==0:
print(1)
else:
print(-1)
break
length>>=1
到了这里,关于异或数列/位运算/数位/二进制的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!