您的位置:首页 > 其它

hdu 2177 取(2堆)石子游戏 (威佐夫博弈)(考虑如何变成奇异局势)

2014-08-19 17:42 260 查看

取(2堆)石子游戏

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

Total Submission(s): 1067 Accepted Submission(s): 641

Problem Description
有两堆石子,数量任意,可以不同。游戏开始由两个人轮流取石子。游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子;二是可以在两堆中同时取走相同数量的石子。最后把石子全部取完者为胜者。现在给出初始的两堆石子的数目,如果轮到你先取,假设双方都采取最好的策略,问最后你是胜者还是败者。如果你胜,你第1次怎样取子?



Input
输入包含若干行,表示若干种石子的初始情况,其中每一行包含两个非负整数a和b,表示两堆石子的数目,a和b都不大于1,000,000,且a<=b。a=b=0退出。



Output
输出也有若干行,如果最后你是败者,则为0,反之,输出1,并输出使你胜的你第1次取石子后剩下的两堆石子的数量x,y,x<=y。如果在任意的一堆中取走石子能胜同时在两堆中同时取走相同数量的石子也能胜,先输出取走相同数量的石子的情况.



Sample Input
1 2 
5 8
4 7
2 2
0 0




Sample Output
0
1
4 7
3 5
0
1
0 0
1 2




Author
Zhousc


Source
ECJTU 2008 Summer Contest
思路:
威佐夫博弈。又是一例没有把握牢固。
威佐夫博弈除了那个基本公式外,
对如何变成奇异局势,有以下判断方式。

/*① a=b时,直接转化成(0,0);

② k=b-a;if (a-ak)=(b-bk); (a-ak)>0,(b-bk)>0

则转化为(a-(a-ak),b-(b-bk));

③ 在ak中可以找到与a相等的,或bk中可以找到与a相等的,则转化为(ak,bk);

以上三种情况中,①与②不会同时出现,③与前两个可以同时出现。*/

代码如下:

#include<stdio.h>
#include<math.h>
int main()
{
	int n,m,i;
	double x=(1.0+sqrt(5))/2;
	while(~scanf("%d%d",&n,&m),n+m)
	{
		if(n>m)
		{
			n^=m;
			m^=n;
			n^=m;
		}
		int k=m-n;
		if(int(k*x)==n)
		printf("0\n");
		else
		{
			printf("1\n");
			for(i=1;i<=n;i++)
			{
				int a=n-i,b=m-i;
				k=b-a;
				if(int(k*x)==a)
				printf("%d %d\n",a,b);
			}
			for(i=m-1;i>=0;i--)
			{
				int a=n;
				int b=i;
				if(a>b)
				{
					a^=b;
					b^=a;
					a^=b;
				}
				k=b-a;
				if(int(k*x)==a)
				printf("%d %d\n",a,b);
			}
		}
	}
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: