题目链接:
http://acm.bnu.edu.cn/v3/problem_show.php?pid=5999
Nim游戏入门题。判断在必胜态时有多少种单步操作可以进入必败态。
解析:
n堆石子,在必胜态时,a1^a2^...^an == k(k大于0),若想单步操作进入必败态,即让某堆石子个数由ai减为bi,使得a1^a2^...^bi^...^an == 0。显然k^k == 0,故可使bi = ai^k ,即满足 ai^k < ai 。如何寻找这样的ai呢?记 k 的二进制最高位为第 x 位(最高位为1)。则一定存在ai,第x位上也为1(因为k的第x位为1,所以一定存在这样的ai,不然k第x位的1哪来的...)。对于这样的ai,一定满足ai^k < ai(想想为什么?)。所以满足这个条件的ai的个数就是我们要求的答案。
代码:
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <map>
#include <queue>
#define LL long long
#define db double
#define pi acos(-1.0)
#define mod
#define N 110
using namespace std;
int c[N];
int pow_int(int a,int b)
{
int r=1;
while(b--)
{
r*=a;
}
return r;
}
int main()
{
int n;
while(scanf("%d",&n)+1&&n)
{
int ans = 0;
int nim_sum=0;
for(int i=0; i<n; ++i)
{
scanf("%d",&c[i]);
nim_sum^=c[i];
}
if(nim_sum==0)
{
ans=0;
}
else
{
int k=0;
while(pow_int(2,k)<=nim_sum)
{
k++;
}
int t=pow_int(2,k-1);
for(int i=0;i<n;++i)
{
if(t&c[i])
ans++;
}
}
printf("%d\n",ans);
}
return 0;
}