hdu1850 Being a Good Boy in Spring Festival(nim博弈)

Being a Good Boy in Spring Festival

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 6682    Accepted Submission(s): 4039

Problem Description

一年在外 父母时刻牵挂

春节回家 你能做几天好孩子吗

寒假里尝试做做下面的事情吧

陪妈妈逛一次菜场

悄悄给爸爸买个小礼物

主动地 强烈地 要求洗一次碗

某一天早起 给爸妈用心地做回早餐

如果愿意 你还可以和爸妈说

咱们玩个小游戏吧 ACM课上学的呢~

下面是一个二人小游戏:桌子上有M堆扑克牌;每堆牌的数量分别为Ni(i=1…M);两人轮流进行;每走一步可以任意选择一堆并取走其中的任意张牌;桌子上的扑克全部取光,则游戏结束;最后一次取牌的人为胜者。

现在我们不想研究到底先手为胜还是为负,我只想问大家:

——“先手的人如果想赢,第一步有几种选择呢?”

Input

输入数据包含多个测试用例,每个测试用例占2行,首先一行包含一个整数M(1<M<=100),表示扑克牌的堆数,紧接着一行包含M个整数Ni(1<=Ni<=1000000,i=1…M),分别表示M堆扑克的数量。M为0则表示输入数据的结束。

Output

如果先手的人能赢,请输出他第一步可行的方案数,否则请输出0,每个实例的输出占一行。

Sample Input

3
5 7 9
0

Sample Output

1

Author

lcy

Source

ACM
Short Term Exam_2007/12/13

题意:中文题.....就不解释了....

分析:一道基础的nim博弈题,知道a^b=c,a^c=b,b^c=a;问题就解决了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;
const double eps = 1e-6;
const double pi = acos(-1.0);
const int INF = 1e9;
const int MOD = 1e9+7;
#define ll long long
#define CL(a,b) memset(a,b,sizeof(a))
#define lson (i<<1)
#define rson ((i<<1)|1)
#define N 50010
int gcd(int a,int b){return b?gcd(b,a%b):a;}

int n,a[110];

int main()
{
    while(scanf("%d",&n),n)
    {
        int sum=0,ans=0;
        for(int i=0; i<n; i++)
        {
            scanf("%d",&a[i]);
            sum ^= a[i];
        }
        if(sum==0){cout<<0<<endl; continue;}
        for(int i=0; i<n; i++)
        {
            if((sum^a[i]) <= a[i]) ans++;
        }
        cout<<ans<<endl;
    }
    return 0;
}
时间: 2024-10-10 14:08:23

hdu1850 Being a Good Boy in Spring Festival(nim博弈)的相关文章

HDU1850 Being a Good Boy in Spring Festival(NIM)

典型nim博弈题,全部异或完以后,sum=0为必败条件. 题目问的是有多少种构造必败的方法. 假设我们取第i堆石子,则其余n-i堆石子不变,状态可以由(sum^i)表示. 如果我们取完这堆石子,使(sum^i)^(new)i=0则成功构造必败条件. 显然这里的(new)i要与(sum^i)相等,所以只需要当前的i>(sum^i)即可构造出必败条件. 遍历一遍统计就好了. #include <iostream> #include <cstdio> #include <cs

hdu1850Being a Good Boy in Spring Festival NiM博弈

//当该点时p-position时,先手输 //当该点为n-position时,即a1^a2......^an = k时; //先手的第一步是使得a1^a2^.......^an^k = 0; //那么只要ai^k < ai就行 #include<iostream> #include<cstdio> #include<cstring> using namespace std ; const int maxn = 10000010 ; int num[maxn] ;

HDU 1850 Being a Good Boy in Spring Festival(nim博弈)

题目地址:HDU 1850 这个博弈论异或这个地方感觉真绕,仔细想了一下,终于把它给理清楚了.总结一下之前不太理解的: 1:在当前操作中,只要可以达到某个必败态,那这个点一定是必胜态的,因为要想获胜,肯定会选择必败态的操作. 2:只有当所有值的异或值为0的时候,才是必败态,所以说对于N堆的nim游戏来说,第一步的操作对于每一堆来说只能有至多一种可以形成必败态.因为另外(n-1)堆的异或值是唯一的,所以当前堆也是唯一的. 3:对于每一堆来说,只要可以剩下一个数,使得这个数与另外(n-1)堆的异或值

HDU1850 Being a Good Boy in Spring Festival(博弈)

Being a Good Boy in Spring Festival Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u Submit Status Description 一年在外 父母时刻牵挂 春节回家 你能做几天好孩子吗 寒假里尝试做做下面的事情吧 陪妈妈逛一次菜场 悄悄给爸爸买个小礼物 主动地 强烈地 要求洗一次碗 某一天早起 给爸妈用心地做回早餐 如果愿意 你还可以和爸妈说 咱们玩个小

HDU1850 Being a Good Boy in Spring Festival

解题报告:题目的意思很简单!就是一个Nim博弈!但是不是问谁获胜,本题而是问的获胜的方法有多少种!首先,我们必须知道,因为是起手,对于M堆扑克,最多有M种获胜的方法!对res = M1 ^ M2 ^ M3 -. ^ Mm取异或(^)得res,由异或的性质知:res ^ Mi = ( M1 ^ M2 -^M(i-1) ^ M(i+1) ^ - ^Mm ) ,也就是说res对任意一个数取^可以的得到其他所有数的^值,例如:5 7 9:5^7^9=0101^0111^1001=1011=11;那么11

HDU1850 Being a Good Boy in Spring Festival(NIM统计)

题意: NIM题,问你第一个人有多少种取的方案 思路: 全部异或完后,然后让这个值分别异或每一个数 如果结果小于当前数,就说明可以从该堆中取走异或这个数这么多石子 ans就++ /* *********************************************** Author :devil Created Time :2016/5/29 11:31:46 ************************************************ */ #include <c

hdu1850 Being a Good Boy in Spring Festival ,尼姆博弈(Mimm game),Min sum

题意: 桌子上有M堆扑克牌:每堆牌的数量分别为Ni(i=1-M): 两人轮流进行:每走一步可以任意选择一堆并取走其中的任意张牌: 桌子上的扑克全部取光,则游戏结束:最后一次取牌的人为胜者. 题解: 尼姆博奕(Nimm Game) 先求所有堆的 Nim-sum = N1 ^ N2 ^ ... NM 然后 res =Nim-sum ^ Ni 如果 res < Ni, 则先手玩家只要第一步从Ni堆中取走Ni-res个, 则剩下的局面Nim-sum = 0, 即为剩下的局面为必败态.则这就一种取胜的方案

hdu 1850 Being a Good Boy in Spring Festival(Nimm Game)

题意:Nimm Game 思路:Nimm Game #include<iostream> #include<stdio.h> using namespace std; int main(){ int m,a[128],i,sum,ans; while(~scanf("%d",&m)&&m){ sum=0; for(i=0;i<m;++i){ scanf("%d",&a[i]); sum^=a[i]; }

ACM-尼姆博弈之Being a Good Boy in Spring Festival——hdu1850

Being a Good Boy in Spring Festival Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3947    Accepted Submission(s): 2328 Problem Description 一年在外 父母时刻牵挂 春节回家 你能做几天好孩子吗 寒假里尝试做做下面的事情吧 陪妈妈逛一次菜场 悄悄