传统的 Nim 游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同)。两个游戏者轮流操作,每次可以选一个火柴堆拿走若干根火柴。可以只拿一根,也可以拿走整堆火柴,但不能同时从超过一堆火柴中拿。拿走最后一根火柴的游戏者胜利。
本题的游戏稍微有些不同:在第一个回合中,第一个游戏者可以直接拿走若干个整堆的火柴。可以一堆都不拿,但不可以全部拿走。第二回合也一样,第二个游戏者也有这样一次机会。从第三个回合(又轮到第一个游戏者)开始,规则和 Nim 游戏一样。
如果你先拿,怎样才能保证获胜?如果可以获胜的话,还要让第一回合拿的火柴总数尽量小。
#include<bits/stdc++.h>
using namespace std; 
#define N 110 
#define ll long long 
int d[N],n,a[N];  
ll sum,ans; 
int ins(int  x){
    for(int i=30;i>=0;i--)  
        if(x&(1<<i)){
            if(d[i]) x^=d[i];  
            else{
                d[i]=x;  
                return 1; 
            }
        }
    return 0;  
}
int main(){
    scanf("%d",&n);  
    for(int i=1;i<=n;i++) 
        scanf("%d",&a[i]),sum+=a[i];  
    for(int i=1;i<n;i++) 
        for(int j=i+1;j<=n;j++) 
            if(a[i]<a[j])
                swap(a[i],a[j]); 
    for(int i=1;i<=n;i++)  
        if(ins(a[i])) ans+=a[i];  
    cout<<sum-ans<<endl; 
    return 0;     
}
原文:https://www.cnblogs.com/ZJXXCN/p/13096169.html