题意:
桌子上有M堆扑克牌;每堆牌的数量分别为Ni(i=1…M);
两人轮流进行;每走一步可以任意选择一堆并取走其中的任意张牌;桌子上的扑克全部取光,则游戏结束;最后一次取牌的人为胜者。
题解:
尼姆博奕(Nimm Game)
Nim-sum = 0 必败态
先求所有堆的 Nim-sum = N1 ^ N2 ^ ... NM
然后
res =Nim-sum ^ Ni
如果 res < Ni, 则先手玩家只要第一步从Ni堆中取走Ni-res个, 则剩下的局面必败态(Nim-sum = 0,)
即为剩下的局面为必败态。则这就一种取胜的方案。
对于每个堆的操作至多只有一种方法可以导败必败态
换汤不换药的题:
poj 2975 Nim Min-sum Bouton定理
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[200];
int main() {
int n;
while(~scanf("%d", &n)&&n) {
int sum = 0;
for(int i=0; i<n; ++i) {
scanf("%d", &a[i]);
sum ^= a[i];
}
int ans = 0;
for(int i=0; i<n; ++i)
if(a[i] > (sum^a[i]) ) ans++;
printf("%d\n", ans);
}
return 0;
}