【 HDU 2177 】取(2堆)石子游戏 (威佐夫博弈)
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)。
只取第二堆:
- 第二堆仍更大:若a在必输态中是较小的数(y[a]!=0),且b>y[a],则可变成(a,y[a])。
- 第二堆更小了:若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堆)石子游戏 (威佐夫博弈)的更多相关文章
- HDU2177:取(2堆)石子游戏(威佐夫博弈)
Problem Description 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同 ...
- HDU 2177 取(2堆)石子游戏
取(2堆)石子游戏 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- HDU 2176:取(m堆)石子游戏(Nim博弈)
取(m堆)石子游戏 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...
- HDU 2177 取(2堆)石子游戏 (威佐夫博弈)
题目思路:威佐夫博弈: 当当前局面[a,b]为奇异局时直接输出0 否则: 1.若a==b,输出(0 0): 2.将a,b不停减一,看能否得到奇异局,若有则输出: 3.由于 ak=q*k(q为黄金分割数 ...
- HDU 2117 取(2堆)石子游戏【wzf博弈】
题意:威佐夫博弈原型,除了输出先手能不能胜,还要输出先手的第一手选择. 思路:预处理出1000000以内的所有奇异局势.对于每个自然数,其必然是某一个奇异局势的a或者b.故对于一个非奇异局势,必定有一 ...
- hdu 2177 取(2堆)石子游戏(威佐夫博奕)
题目链接:hdu 2177 这题不是普通的 Nim 博弈,我想它应该是另一种博弈吧,于是便推 sg 函数打了个 20*20 的表来看,为了方便看一些,我用颜色作了标记,打表代码如下: #include ...
- HDU-2177 取(2堆)石子游戏 (威佐夫博奕)
Problem Description 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同 ...
- hdu 2177 取(2堆)石子游戏 博弈论
由于要输出方案,变得复杂了.数据不是很大,首先打表,所有whthoff 的奇异局势. 然后直接判断是否为必胜局面. 如果必胜,首先判断能否直接同时相减得到.这里不需要遍历或者二分查找.由于两者同时减去 ...
- HDU 2176 取(m堆)石子游戏 —— (Nim博弈)
如果yes的话要输出所有情况,一开始觉得挺难,想了一下也没什么. 每堆的个数^一下,答案不是0就是先取者必胜,那么对必胜态显然至少存在一种可能性使得当前局势变成必败的.只要任意选取一堆,把这堆的数目变 ...
- HDU 2176 取(m堆)石子游戏 尼姆博弈
题目思路: 对于尼姆博弈我们知道:op=a[1]^a[2]--a[n],若op==0先手必败 一个简单的数学公式:若op=a^b 那么:op^b=a: 对于第i堆a[i],op^a[i]的值代表其余各 ...
随机推荐
- Codeforces Round #485 (Div. 2)-B-High School: Become Human
B. High School: Become Human time limit per test 1 second memory limit per test 256 megabytes input ...
- JQuery 的Ajax的使用
JSON:一种轻量级的数据表示方法,优点:传输方便,占用字节少 XML:一种偏重量级的数据表示方法,优点:格式清晰,占用字节多,大量的字节都浪费在了标签上: 网络传输我们常使用json,因为浏览器解析 ...
- snappy
Snappy 是一个 C++ 的用来压缩和解压缩的开发包.其目标不是最大限度压缩或者兼容其他压缩格式,而是旨在提供高速压缩速度和合理的压缩率.Snappy 比 zlib 更快,但文件相对要大 % 到 ...
- Jmeter操作之跨线程组传递参数
思路:将某一线程组内的变量通过“__setProperty”函数设置成jmeter的全局变量,在另一线程组中通过“__P”函数调用即可. 1.添加-后置处理器-BeanShell PostProces ...
- Mysql drop function xxxx ERROR 1305 (42000): FUNCTION (UDF) xxxx does not exist
mysql> drop function GetEmployeeInformationByID;ERROR 1305 (42000): FUNCTION (UDF) GetEmployeeInf ...
- IdentityServer4【Introduction】之术语
术语 在规范.文档和对象模型中使用了一些你应该了解的术语. IdentityServer IdentityServer是一个OpenID Connect的提供者,它实现了OpenID Connect和 ...
- css太极
自己用css做的太极,留个纪念. 用css做太极有很多种实现方法,我这种大概是最简单的了吧,因为div用得太多了,哈哈. 高级一点的应该是用伪类:before和:after去减少div的用量(手动滑稽 ...
- MySQL 字段内容区分大小写
数据由Oracle 迁入MySQL ,由于之前Oracle区分大小写,MySQL的配置使用了默认配置,导致一些数据导入失败,有的唯一键报错,冲突. 将测试过程记录在下面. 数据库版本:MySQL 5. ...
- vscode git設置
1.git官网https://git-scm.com/download/win 链接下载:64-bit Git for Windows Setup,不要下载Portable,体积太大了: 如果git官 ...
- vue环境搭建+vscode
https://blog.csdn.net/junshangshui/article/details/80376489