传统的 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