威佐夫博弈
2016-07-07 18:44
183 查看
威佐夫博弈:
有两堆各若干个物品,两个人轮流从某一堆或同时从两堆中取同样多的物品,规定每次至少取一个,多者不
限,最后取光者得胜。
例题:HDU 1527:取石子游戏
http://acm.hdu.edu.cn/showproblem.php?pid=1527
我们将情景设为取苹果,再设两堆苹果数量为(a,b),现规定T态为必输态(谁面对这种状态谁必输),其他都为S
态必赢态,可以得出前几个T态分别为(0,0)、(1,2)、(3,5)、(4,7)、(6,10)、(8,13)、(9,15)、(11,18)、(12,20),它们有
以下几点性质:
①设a[i]为第i个T态的a堆,b[i]为第i个T态的b堆,那么显然b[i]-a[i]==i && a[i]是在前面从未出现过的最小自然数
②任何一个自然数都可以出现在T态中
③对于T态,无论怎么取都将变为S态,对于S态,一定有方法取成T态,(0,0)属于T态,这也是为什么S态为必
赢态,T必输
④(a,b)和(b,a)等效
(以上具体证明见"威佐夫博奕"百度百科)
那么问题来了,给定一组(a,b)如何判断它是不是T态,显然只要找到它是第几个T态即可,已知公式a[i] = (int)
(i*(sqrt(5)+1)/2),b[i] = a[i]+i,那么就可以通过i = a[i]*(sqrt(5)-1)/2)求出i的值,当然有可能出现精度缺失,所以有可
能算出的i值比实际i值小1,接下来判断a[i]是否满足a[i] = (int)(i*(sqrt(5)+1)/2),如果满足,那么看b[i]是否满足b[i]
= a[i]+i,如果全部满足说明为T态,否则为S态
#include<stdio.h>
#include<math.h>
#include<algorithm>
using namespace std;
int main(void)
{
int a, b, n;
double Gv;
Gv = (sqrt(5.0)+1)/2.0;
while(scanf("%d%d", &a, &b)!=EOF)
{
if(a>b)
swap(a, b);
n = a*(Gv-1);
if(a==(int)(n*Gv) && a+n==b || a==(int)((n+1)*Gv) && a+n+1==b)
printf("0\n");
else
printf("1\n");
}
return 0;
}
有两堆各若干个物品,两个人轮流从某一堆或同时从两堆中取同样多的物品,规定每次至少取一个,多者不
限,最后取光者得胜。
例题:HDU 1527:取石子游戏
http://acm.hdu.edu.cn/showproblem.php?pid=1527
我们将情景设为取苹果,再设两堆苹果数量为(a,b),现规定T态为必输态(谁面对这种状态谁必输),其他都为S
态必赢态,可以得出前几个T态分别为(0,0)、(1,2)、(3,5)、(4,7)、(6,10)、(8,13)、(9,15)、(11,18)、(12,20),它们有
以下几点性质:
①设a[i]为第i个T态的a堆,b[i]为第i个T态的b堆,那么显然b[i]-a[i]==i && a[i]是在前面从未出现过的最小自然数
②任何一个自然数都可以出现在T态中
③对于T态,无论怎么取都将变为S态,对于S态,一定有方法取成T态,(0,0)属于T态,这也是为什么S态为必
赢态,T必输
④(a,b)和(b,a)等效
(以上具体证明见"威佐夫博奕"百度百科)
那么问题来了,给定一组(a,b)如何判断它是不是T态,显然只要找到它是第几个T态即可,已知公式a[i] = (int)
(i*(sqrt(5)+1)/2),b[i] = a[i]+i,那么就可以通过i = a[i]*(sqrt(5)-1)/2)求出i的值,当然有可能出现精度缺失,所以有可
能算出的i值比实际i值小1,接下来判断a[i]是否满足a[i] = (int)(i*(sqrt(5)+1)/2),如果满足,那么看b[i]是否满足b[i]
= a[i]+i,如果全部满足说明为T态,否则为S态
#include<stdio.h>
#include<math.h>
#include<algorithm>
using namespace std;
int main(void)
{
int a, b, n;
double Gv;
Gv = (sqrt(5.0)+1)/2.0;
while(scanf("%d%d", &a, &b)!=EOF)
{
if(a>b)
swap(a, b);
n = a*(Gv-1);
if(a==(int)(n*Gv) && a+n==b || a==(int)((n+1)*Gv) && a+n+1==b)
printf("0\n");
else
printf("1\n");
}
return 0;
}
相关文章推荐
- C#任意变换图像大小
- 颜色渐变、#16进制转RGB颜色(转Int)
- iOS SDWebImage 淡入 UITableViewCell
- C++中ANSI、Unicode、UTF8字符串之间的互转
- 支持向量机(五)SMO算法
- Android异常解决--A WebView method was called on thread 'JavaBridge'. All WebView methods must be called
- KVM 虚拟化架构和实现原理
- 异常篇之Activity class {} does not exist(AS)
- UIButton 的图文混排
- linux 快速分析JVM信息
- 浅谈Android开发中内存泄露与优化-------其一
- Ubuntu下github pages+hexo搭建自己的博客
- Objective-C——Block的使用
- session详解
- Ubuntu下github pages+hexo搭建自己的博客
- 项目经验(持续更新)
- 【计算机视觉】Visual Tracking 领域最新进展(论文与源码)
- java反射学习总结
- 随记
- Linux下iptables 禁止端口和开放端口