博弈论 (Nim 博弈)—— HDU 1907 && HDU 2509

来源:互联网 发布:c语言数组长度最大多少 编辑:程序博客网 时间:2024/06/05 09:24
  • 题目链接:
    http://acm.hdu.edu.cn/showproblem.php?pid=1907

  • 分析:
    这是一道非常经典的Nim博弈,我们需要特殊判断一下每一堆石子都为1的情况,然后对于其它情况,只需要将每一堆石子的数量异或在一起,最终为1就是先手先拿完,为0就是后手先拿完。

  • 算法证明:
    http://blog.csdn.net/acm_cxlove/article/details/7854530#comments

  • AC代码:

#include<iostream>const int MAX=5000;using namespace std;int t,m;int x[MAX];int main(){    while(cin>>t)    {        while(t--)        {            cin>>m;            int q=0;            for(int i=0;i<m;i++)            {                cin>>x[i];                if(x[i]==1)                q+=1;            }            if(q==m)            {                if(q%2!=0)                cout<<"Brother"<<endl;                else                cout<<"John"<<endl;                continue;            }            int p=x[0];            for(int i=1;i<m;i++)            {                p^=x[i];            }            if(m==1)            {                cout<<"John"<<endl;                continue;            }            if(p)            cout<<"John"<<endl;            else            cout<<"Brother"<<endl;        }    }    return 0;}

HDU 2509这道题几乎也是一样,只需要异或每一堆苹果就可以。

  • AC代码:
#include <iostream>#include <cstdio>#include <cstring>using namespace std;int n;int apple[110];int main(){    while(~scanf("%d", &n))    {        int m = 0;        for(int i=0;i<n;i++)        {            scanf("%d", &apple[i]);            if(apple[i] == 1)              m++;        }        if(m == n)        {            if(n&1)              cout << "No\n";            else              cout << "Yes\n";        }        else        {            for(int i=1;i<n;i++)            {                apple[0]^=apple[i];            }            if(apple[0])              cout << "Yes\n";            else              cout << "No\n";        }    }    return 0
0 0