BUPT2017 wintertraining(15) #5C

hdu2177

题意

两个人轮流取石子,可以取一堆的任意非负整数个或两堆取相同个,先取完的输。

给定若干组数据:a,b表示两堆的石子数量,求先手输还是赢,赢还要求第一步之后的两堆石子数,如果有取相同的方案,先输出。

题解

威佐夫博弈问题。

必输的状态(奇异局势):(0,0),(1,2),(3,5),..(a_k,a_k+k)其中a_k是前面未出现过的最小的正整数。

有一些性质:每个正整数在必输状态中出现且仅出现一次。

于是可以计算并存储下必输状态(X,Y),x[k]为第k个必输状态的较小的数,y[i]为必输状态中是较小的数i 对应的较大的数,z[i]为必输状态中较大的数i 对应的较小的数。

先手输的情况就是一开始就是必输态,也就是k=b-a,x[k]==a。

先手赢的情况,是将局面变成必输态:

取走两个相同的数后,差k不变,若a>x[k],则可变成(x[k],y[x[k]])。

只取第一堆:

若b在它所在的必输态中是较大的数(z[b]!=0),且a>z[b],则可变成(z[b],b)。

只取第二堆:

  1. 第二堆仍更大:若a在必输态中是较小的数(y[a]!=0),且b>y[a],则可变成(a,y[a])。
  2. 第二堆更小了:若a在必输态中是较大的数,因为b>a>z[a],可以变成(z[a],a)。

这题数据比较水,错误的代码也ac了。按我现在的思路我也不敢说一定是正确的代码。

另外也可以用公式直接求出奇异局势:

$a_k = [k\cdot (1+√5)/2],b_k= a_k + k $

代码

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#define N 1000005
using namespace std;
int a,b,vis[N<<1],x[N],y[N],z[N<<1],k;
int main() {
for(int i=1;i<N;i++)
if(!vis[i]){
x[++k]=i;y[i]=i+k;z[i+k]=i;
vis[i]=vis[y[i]]=1;
}
while(scanf("%d%d",&a,&b),a||b){
if(x[b-a]==a)
puts("0");
else{
puts("1");
if(a>x[b-a]) printf("%d %d\n",x[b-a],y[x[b-a]]);
if(z[b]&&a>z[b]) printf("%d %d\n",z[b],b);
if(y[a]&&b>y[a]) printf("%d %d\n",a,y[a]);
if(z[a])printf("%d %d\n",z[a],a);
}
}
return 0;
}

【 HDU 2177 】取(2堆)石子游戏 (威佐夫博弈)的更多相关文章

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

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

  2. HDU 2177 取(2堆)石子游戏

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

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

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

  4. HDU 2177 取(2堆)石子游戏 (威佐夫博弈)

    题目思路:威佐夫博弈: 当当前局面[a,b]为奇异局时直接输出0 否则: 1.若a==b,输出(0 0): 2.将a,b不停减一,看能否得到奇异局,若有则输出: 3.由于 ak=q*k(q为黄金分割数 ...

  5. HDU 2117 取(2堆)石子游戏【wzf博弈】

    题意:威佐夫博弈原型,除了输出先手能不能胜,还要输出先手的第一手选择. 思路:预处理出1000000以内的所有奇异局势.对于每个自然数,其必然是某一个奇异局势的a或者b.故对于一个非奇异局势,必定有一 ...

  6. hdu 2177 取(2堆)石子游戏(威佐夫博奕)

    题目链接:hdu 2177 这题不是普通的 Nim 博弈,我想它应该是另一种博弈吧,于是便推 sg 函数打了个 20*20 的表来看,为了方便看一些,我用颜色作了标记,打表代码如下: #include ...

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

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

  8. hdu 2177 取(2堆)石子游戏 博弈论

    由于要输出方案,变得复杂了.数据不是很大,首先打表,所有whthoff 的奇异局势. 然后直接判断是否为必胜局面. 如果必胜,首先判断能否直接同时相减得到.这里不需要遍历或者二分查找.由于两者同时减去 ...

  9. HDU 2176 取(m堆)石子游戏 —— (Nim博弈)

    如果yes的话要输出所有情况,一开始觉得挺难,想了一下也没什么. 每堆的个数^一下,答案不是0就是先取者必胜,那么对必胜态显然至少存在一种可能性使得当前局势变成必败的.只要任意选取一堆,把这堆的数目变 ...

  10. HDU 2176 取(m堆)石子游戏 尼姆博弈

    题目思路: 对于尼姆博弈我们知道:op=a[1]^a[2]--a[n],若op==0先手必败 一个简单的数学公式:若op=a^b 那么:op^b=a: 对于第i堆a[i],op^a[i]的值代表其余各 ...

随机推荐

  1. rest-framework序列化

    快速实例 Quickstart 序列化 开篇介绍: ---- 一切皆是资源,操作只是请求方式 ----book表增删改查 /books/ books /books/add/ addbook /book ...

  2. 常见的 CSRF、XSS、sql注入、DDOS流量攻击

    CSRF攻击 :跨站请求伪造攻击 ,CSRF全名是Cross-site request forgery,是一种对网站的恶意利用,CSRF比XSS更具危险性 攻击者一般会使用吸引人的图片去引导用户点击进 ...

  3. 使用docker化的nginx 反向代理 docker化的GSCloud 的方法

    1. 首先将nginx 的image pull 下来. docker pull nginx 2. 将最近的可用的 参数文件 复制过来当一个目录 mkdir /nginx ssh root@linuxs ...

  4. childNodes遍历DOM节点树

    childNodes遍历DOM节点树 var s = ""; function travel(space,node) { if(node.tagName){ s += space ...

  5. JS --- 如何获取一个对象的类型

    可以清楚的看到  拿到数字 字符串 对象 函数 数组 通过.slice(8,-1) 可以拿到类型的名称 ,可以做你想要的操作 Object.prototype.toString.call(222) & ...

  6. Hbase的作用

    实时动态增加列 多版本的意思为多个用户地址,多个用户信息,多个用户号码

  7. 浅谈WPF中的PreviewTextInput

    今天在使用TextBox的TextInput事件的时候,发现无论如何都不能触发该事件,然后百思不得其解,最后在MSDN上找到了答案:TextInput 事件可能已被标记为由复合控件的内部实现进行处理. ...

  8. font_awesome的icon库的使用

    1.使用cdn引入font_awesome图标库的css文件 例如:index.htm <html><head><title>font_awesome test&l ...

  9. AVL树,红黑树

    AVL树 https://baike.baidu.com/item/AVL%E6%A0%91/10986648 在计算机科学中,AVL树是最先发明的自平衡二叉查找树.在AVL树中任何节点的两个子树的高 ...

  10. Eclipse:报错Failed to read artifact descriptor for org.springframework.boot:spring-boot-autoconfigure:jar:2.1.2.

    导入SVN下载的MAVEN项目时springboot报错: pom.xml文件报错 Failed to read artifact descriptor for org.springframework ...