天天看点

简单博弈10道

hdu1846巴什博弈,n%(m+1)==0先手必败。

#include <iostream>

#include<cstdio>

#include<cstring>

#include<cstdlib>

#include<cmath>

using namespace std;

int main()

{

    int n,a,b;

    scanf("%d",&n);

    while(n--)

    {

        scanf("%d%d",&a,&b);

        if(a%(b+1)==0)

        printf("second\n");

        else printf("first\n");

    }

    return 0;

}

hdu1847

只要留下两类都是2的指数幂,就是必输状态,然后找规律,发现这两类的和为3的倍数。即有下面的结论。

#include <iostream>

#include<cstdio>

#include<cmath>

using namespace std;

int main()

{

   int n;

   while(scanf("%d",&n)!=EOF)

   {

       if(n%3==0)

       printf("Cici\n");

       else printf("Kiki\n");

   }

    return 0;

}

hdu1848

#include <iostream>

#include<cstdio>

#include<cmath>

#include<cstring>

using namespace std;

#define N 1005

int f[N];

int sg[N];

void fun()

{

    int i;

    f[0]=1;

    f[1]=1;

    f[2]=2;

    for(i=3;;i++)

    {

    f[i]=f[i-1]+f[i-2];

    if(f[i]>1000)

    break;

    }

}

int dfs(int v)

{

    int i;

    if(sg[v]!=-1)

    return sg[v];

    bool visit[N]={0};

    for(i=1;i<16;i++)

    {

       if(v>=f[i])

       {

           int temp=dfs(v-f[i]);

           visit[temp]=1;

       }

    }

    for(i=0;visit[i];i++);

    return sg[v]=i;

}

int main()

{

    fun();

    int m,n,p;

    while(scanf("%d%d%d",&m,&n,&p),m||n||p)

    {

        memset(sg,-1,sizeof(sg));

        int ans;

        ans=dfs(m)^dfs(n)^dfs(p);

        if(ans)

        printf("Fibo\n");

        else printf("Nacci\n");

    }

    return 0;

}

hdu1849

裸的NIM博弈,直接异或即可。

#include <iostream>

#include<cstdio>

using namespace std;

int main()

{

    int n,p;

    while(scanf("%d",&n)!=EOF)

    {

        if(n==0)break;

        int ans=0;

        for(int i=0;i<n;i++)

        {

            scanf("%d",&p);

            ans^=p;

        }

        if(ans==0)

        printf("Grass Win!\n");

        else printf("Rabbit Win!\n");

    }

    return 0;

}

hdu1850

简单NIM博弈,如果异或不为0,找出异或可以使其成为0的值, if(num[j]>(ans^num[j]))这是关键。

#include <iostream>

#include<cstdio>

#include<cmath>

#include<cstring>

using namespace std;

int num[105];

int main()

{

    int t;

    while(scanf("%d",&t)&&t)

    {

        int ans=0;

        for(int i=0;i<t;i++)

        {

            scanf("%d",&num[i]);

            ans^=num[i];

        }

        int cnt=0;

        for(int j=0;j<t;j++)

        {

            if(num[j]>(ans^num[j]))

            {

            cnt++;

            }

        }

        printf("%d\n",cnt);

    }

    return 0;

}

hdu1851j简单NIM博弈

#include <iostream>

#include<cstdio>

#include<cmath>

#include<cstdlib>

#include<cstring>

using namespace std;

int main()

{

    int t,n,m,l;

    scanf("%d",&t);

    while(t--)

    {

        scanf("%d",&n);

        int ans=0;

        while(n--)

        {

            scanf("%d%d",&m,&l);

            ans^=(m%(l+1));

        }

        if(ans==0)

        printf("Yes\n");

        else printf("No\n");

    }

    return 0;

}

hdu1907 NIM博弈,全是1的时候,特判,数1的个数,奇数输,偶数赢了。

#include <iostream>

#include<cstdio>

#include<cmath>

#include<cstring>

#include<cstdlib>

using namespace std;

int main()

{

    int t,num;

    scanf("%d",&t);

    while(t--)

    {

        int ans=0,flag=0;

        int p[50];

        scanf("%d",&num);

        for(int i=0; i<num; i++)

        {

            scanf("%d",&p[i]);

            if(p[i]!=1)

                flag=1;

            ans^=p[i];

        }

        if(flag)

        {

            if(ans==0)

                printf("Brother\n");

            else printf("John\n");

        }else

        {

            if(num%2!=0)

                printf("Brother\n");

            else printf("John\n");

        }

    }

    return 0;

}

hdu2147

判断P和N的状态,画出图标即可。利用SG函数的基本性质。P后面的都是N,N后面的一定存在一个P状态。

观察图表规律知道,n和m都是奇数时候,必败。

#include <iostream>

#include<cstdio>

#include<cstring>

#include<cmath>

#include<cstring>

using namespace std;

int main()

{

    int n,m;

    while(scanf("%d%d",&n,&m)!=EOF)

    {

        if(n==0&&m==0)break;

        if(n&1&&m&1)

        printf("What a pity!\n");

        else printf("Wonderful!\n");

    }

    return 0;

}

hdu2148

简单的巴什博弈。

#include <iostream>

#include<cstdio>

#include<cmath>

#include<cstdlib>

#include<cstring>

using namespace std;

int main()

{

    int m,n;

    while(scanf("%d%d",&m,&n)!=EOF)

    {

        if(m%(n+1)==0)

        {

        printf("none\n");

        continue;

        }

        else if(n>m)

        {

            for(int i=m;i<n;i++)

            printf("%d ",i);

            printf("%d\n",n);

        }

        else printf("%d\n",m%(n+1));//这里是开始的时候,如果先出m%(n+1)个,那么剩下的就是必败态了。

    }

    return 0;

}

hdu2149 简单的巴什博弈,同上题类似。

#include <iostream>

#include<cstdio>

using namespace std;

int main()

{

    int t,n,m;

    scanf("%d",&t);

    while(t--)

    {

        scanf("%d%d",&n,&m);

        if(m>n)

        printf("Grass\n");

        else if(n%(m+1)==0)

        {

            printf("Rabbit\n");

        }

        else printf("Grass\n");

    }

    return 0;

}