花生米(三)

时限:1000ms 内存限制:10000K  总时限:3000ms

描述:

五一长假第三天,Tom和Jerry在仓库散步的时候又发现了一堆花生米(仓库,又见仓库……)。这次Tom制定分花生米规则如下:

1、Tom和Jerry轮流从堆中取出k粒花生米吃掉;

2、第一次取花生米的人只能取一粒,以后取花生米的数量不能超过前一个人取花生米数量的两倍;

3、为显示规则的公平性,Jerry可以选择先取或者后取。

Jerry当然还是希望最后一粒花生米被Tom吃掉。请计算,Jerry为了达到目的应该先取还是后取。

输入:

本题有多个测例,每个测例的输入是一个整数n,n大于零小于等于1000,代表花生米的数量。

n等于0表示输入结束,不需要处理。

输出:

每个测例在单独的一行内输出一个整数:Jerry先取输出1;Tom先取输出0。

输入样例:

1

2

3

4

5

0

输出样例:

0

1

0

0

1

#include <stdio.h>

int n;

int List[1001][1001]={0};//List[i][j]:剩余i粒花生米后,第一次最多取j粒花生米



void search()

{

   for(int i=2;i<=n;i++)//剩余i粒花生米

   {

        for(int j=1;j<i-1;j++)//(j=0~i-2)当前最多取j粒花生米

        {

            int flag = 0;

            for(int k=1; k<=j; k++) //测试:当前取k(1~j)粒花生米后        

            {    

                //后一次剩余i-k粒花生米,最多取2*k粒花生米

                if(!List[i-k][2*k])//List[i-k][2*k]=0,即后一次若应由Tom先取才会赢,则标记,当前Jerry先取

                {  flag = 1;   break; }

            }

            List[i][j] = flag;//List[i-k][2*k]都为1,flag仁为0,即取走k粒花生米后,总是Jerry先取才会赢则当前让Tom先取

        }

        //当前可取的花生米数量(j)已经>=剩余数量(i)-1,则Jerry只需取走i-1粒便可让Tom取最后一粒

        for(j=i-1;j<=n;j++)//(j=i-1~n)Jerry先取

             List[i][j] = 1;

   }

   printf("%d\n",List[n][1]); //最初剩余n粒花生米,第一次最多取1粒花生米

}

int main()

{

    scanf("%d",&n);//第一个测例花生米数量n

    while(n!=0)

    {

        search();

        scanf("%d",&n);

    }

    return 0;

}

你可能感兴趣的:(花生米(三))