首先我们不难看出如果存在一个异或和为0的子集,那么先手必胜,否则先手必败

证明如下:

1、首先如果至少存在一个异或和为0的子集,那么一定存在一个异或和为0的子集使得选取之后剩下的数的任意子集异或和不为0

2、假设我们已经选取了一个异或和为0的子集,无论后手怎么做,我们总是有办法使得当前选取的子集异或和为0

->因为后手无论是拿石子还是取石子之后,当前子集异或和不等于0,根据Nim游戏可知,此时先手一定有方案使得异或和为0

至此,我们证明了如果至少存在一个异或和为0的子集,先手必胜

那么我们可以知道

1、如果不存在一个异或和为0的子集,那么先手无论怎么选取,其选取后子集异或和不为0

2、由上述可知,后手一定有方案可以使得当前子集异或和为0,此时先手必败

所以我们证明了如果不存在一个异或和为0的子集,先手必败

 

那么我们就需要求是否存在一个子集异或和为0

首先数据范围很小,我们可以暴力

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cstdlib>
#include<algorithm>
using namespace std;
 
typedef long long LL;
int T,n;
int Num[32];
bool f;
 
void DFS(int p,int tot,int now){
    if(p>n){
        if(tot&&now==0)f=true;
        return;
    }
    DFS(p+1,tot+1,now^Num[p]);
    DFS(p+1,tot,now);
}
 
int main(){
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        for(int i=1;i<=n;++i)scanf("%d",&Num[i]);
        f=false;
        DFS(1,0,0);
        if(f)printf("Yes\n");
        else printf("No\n");
    }return 0;
}
DFS

相关文章: