Nim博弈
題意:有m堆牌,兩個人先後取某堆中的任意(不少於一)張牌,最後取完者勝;問先手取勝第一次取牌有多少種取法。
思路:1)如若給出 的是必敗狀態:a1^a2^......^an=0,則先手不會有任何可能獲得勝利;
2)若給出的是必勝狀態:a1^a2^.......^an=k,(其中k不為零),那麼我們的目的是要把必勝狀態
轉化為必敗狀態從 而使得先手勝利。若a1^a2^...^an!=0,一定存在某個合法的移動,將ai
改變成ai'後滿足a1^a2^...^ai'^...^an=0。若a1^a2^...^an=k,則一定存在某個ai,
它的二進制 表示在k的最高位上是1(否則k的最高位那個1是怎麼得到的)。這時ai^k<ai一定
成立。則我們可以將ai改變成ai'=ai^k,此時a1^a2^...^ai'^...^an=a1^a2^...^an^k=0。
[cpp]
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
int a[102],m,i,sum,s,count;
while(scanf("%d",&m)!=EOF&&m)
{
sum=count=0;
for(i=0;i<m;i++)
{
scanf("%d",&a[i]);
sum=sum^a[i];
}
for(i=0;i<m;i++)
{
s=sum^a[i];
if(s<a[i])
count++;
}
printf("%d\n",count);
}
return 0;
}