题目链接:
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;
}
本文解析了一道Nim游戏入门题,介绍了如何通过异或运算确定必胜状态下可达到必败状态的操作数量,并提供了实现代码。
280

被折叠的 条评论
为什么被折叠?



