和nim游戏类似
易证必败状态为:当前打开的箱子中石子异或和为0,没打开的箱子中不存在一个子集满足异或和为0
因为先手无论是取石子还是开箱子,后手都可以通过取石子来使状态变回原状态
所以只需判定是否有子集异或和等于零即可
#include#include #include #include #include using namespace std;int T,n,a[25];bool work(){ int i,j,k=0; for(i=1<<30;i;i>>=1){ for(j=k+1;j<=n;j++) if(a[j]&i) break; if(j==n+1) continue; swap(a[++k],a[j]); for(j=1;j<=n;j++) if(j!=k&&(a[j]&i)) a[j]^=a[k]; } return k!=n;//k!=n说明有某堆在过程中被异或为0 }int main(){ freopen("hunger.in","r",stdin); freopen("hunger.out","w",stdout); scanf("%d",&T); while(T--){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); if(work()) printf("Yes\n"); else printf("No\n"); } return 0;}