【HDU】Being a Good Boy in Spring Festival

来源:互联网 发布:魅族阿里云系统好用吗 编辑:程序博客网 时间:2024/05/30 19:35

题目链接:

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 110using 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;}

0 0