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
 

明显的威佐夫博弈题

其实这道题的关键就在于对威佐夫博弈的理解

首先我们来看这道题所涉及的一部分威佐夫博弈的主要知识点

0,0)、(1,2)、(3,5)、(4,7)、(6,10)、(8,13)、(9,15)、(11,18)、(12,20)。

可以看出,a0=b0=0,ak是未在前面出现过的最小自然数,而 bk= ak + k,

由此我们可以进行一次奇异状态的打表,再枚举所有的状态即可

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <map>
#include <algorithm>
using namespace std; int ans[1000005][2],len;
int hash[2000005];
map<int,map<int,int> > vis; int main()
{
int a,b,i,j,pos;
memset(hash,0,sizeof(hash));
hash[0] = 1;
double k = (sqrt(5)-1.0)/2.0;
ans[0][0] = ans[0][1] = 0;
len = 1;
for(i = 1; i<=1000000; i++)
{
a = i;
j = a*k;
if(a != (int)(j*(1+k)))
j++;
b = a+j;
if(b>1000000)
break;
if(hash[a])
continue;
ans[len][0] = a;
ans[len][1] = b;
hash[a] = hash[b] = 1;
len++;
}
while(~scanf("%d%d",&a,&b),a+b)
{
vis.clear();
if(a>b)
swap(a,b);
j = a*k;
if(a != (int)(j*(1+k)))
j++;
if(a+j == b)
printf("0\n");
else
{
printf("1\n");
if(a == b)//相同可以取完
{
printf("0 0\n");
vis[0][0] = 1;
}
else//我们知道b = a+k,并且可以发现,在奇异状态之中,a,b的差正好就是其位于数组的下标,由此我们可以突出这个状态
{
int k = b-a;
if(b-ans[k][1]==a-ans[k][0]&&b-ans[k][1]>0&&a-ans[k][0]>0)
printf("%d %d\n",ans[k][0],ans[k][1]);
vis[ans[k][0]][ans[k][1]]=1;
}
for(i = 0; i<len; i++)//剩下的就是简单的枚举了,由于奇异状态中,后面的是大的,所以当a在后面出现的话就枚举完了
{
if(a == ans[i][0] && !vis[ans[i][0]][ans[i][1]])
printf("%d %d\n",ans[i][0],ans[i][1]);
if(a == ans[i][1] && !vis[ans[i][0]][ans[i][1]])
{
printf("%d %d\n",ans[i][0],ans[i][1]);
break;
}
}
}
} return 0;
}

HDU2177:取(2堆)石子游戏(威佐夫博弈)的更多相关文章

  1. HDU-2177 取(2堆)石子游戏 (威佐夫博奕)

    Problem Description 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同 ...

  2. HDU2177取(2堆)石子游戏---(威佐夫博弈)

    http://acm.hdu.edu.cn/showproblem.php?pid=2177 取(2堆)石子游戏 Time Limit: 3000/1000 MS (Java/Others)    M ...

  3. HDU 2176:取(m堆)石子游戏(Nim博弈)

    取(m堆)石子游戏 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...

  4. nim3取石子游戏 (威佐夫博弈)

    http://www.cnblogs.com/jackge/archive/2013/04/22/3034968.html 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有 ...

  5. HDU 1527 取石子游戏(威佐夫博弈)

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission( ...

  6. 洛谷P2252 取石子游戏(威佐夫博弈)

    题目背景 无 题目描述 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同数量的石子.最后 ...

  7. hdu1527取石子游戏(威佐夫博弈)

    取石子游戏 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...

  8. P2252 取石子游戏 威佐夫博弈

    $ \color{#0066ff}{ 题目描述 }$ 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆 ...

  9. POJ 1067 取石子游戏 威佐夫博弈

    威佐夫博弈(Wythoff Game):有两堆各若干个物品,两个人轮流从某一堆或同时从两堆中取同样多的物品,规定每次至少取一个,多者不限,最后取光者得胜. 我们用(ak,bk)(ak ≤ bk ,k= ...

随机推荐

  1. WPF之小动画一

    定义动画: 直接使用Element进行BeginAnimation DoubleAnimation animation = new DoubleAnimation(); animation.By = ...

  2. 强强合体:Docker版Kali Linux发布

    Kali Linux是一款开源的基于Debian的渗透测试专用操作系统,系统中包含一系列用于渗透测试的神器.最近,Kali的开发者们为喜爱Docker的童鞋们发布了新版本. FreeBuf百科:什么是 ...

  3. C#.Net 如何动态加载与卸载程序集(.dll或者.exe)2----通过应用程序域AppDomain加载和卸载程序集之后,如何再返回原来的主程序域

    实现目的:动态加载dll,执行完毕之后可以随时卸载掉,并可以替换这些dll,以在运行中更新dll中的类. 其实就是通过应用程序域AppDomain加载和卸载程序集. 在这方面微软有篇文章http:// ...

  4. 查看Linux系统的版本以及位数

    1.查看版本 http://jingyan.baidu.com/article/215817f7e360bd1edb142362.html[root@localhost usr]# lsb_relea ...

  5. [LOJ 1030] Discovering Gold

    B - Discovering Gold Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu ...

  6. Java [leetcode 29]Divide Two Integers

    题目描述: Divide two integers without using multiplication, division and mod operator. If it is overflow ...

  7. ora-28001:口令失效

    Oracle11G创建用户时缺省密码过期限制是180天(即6个月), 如果超过180天用户密码未做修改则该用户无法登录. Oracle公司是为了数据库的安全性默认在11G中引入了这个默认功能,但是这个 ...

  8. 【转】FTS抓包看蓝牙的SDP整个过程

    原文网址:http://blog.sina.com.cn/s/blog_69b5d2a50101f23c.html 1.概述   SDP是蓝牙的Service Discovery Protocol,用 ...

  9. 【转】特斯拉CEO马斯克:关于创业的几件重要事情

    特斯拉电动汽车联合创始人兼CEO,私人太空发射公司SpaceX CEO伊隆马斯克(Elon Musk)于5月16日在南加大商学院毕业典礼上发表演讲,他谈到了关于创业的几件重要的事情:一是努力工作;二是 ...

  10. Hibernate4.x之Session--常用方法

    接上篇文章继续学习Hibernate的Session(http://www.cnblogs.com/dreamfree/p/4111777.html) 持久化对象的状态; 站在持久化的角度,Hiber ...