hdu1527-威佐夫博弈(Wythoff Game)
来源:互联网 发布:linux chgrp 单词 编辑:程序博客网 时间:2024/04/27 13:16
hdu1527-威佐夫博弈
Problem Description
有两堆石子,数量任意,可以不同。游戏开始由两个人轮流取石子。游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子;二是可以在两堆中同时取走相同数量的石子。最后把石子全部取完者为胜者。现在给出初始的两堆石子的数目,如果轮到你先取,假设双方都采取最好的策略,问最后你是胜者还是败者。
首先,我们想到打表查看,小规模博弈情况:
程序如下:
方法一:
#include <iostream>#include <cstdio>using namespace std;int d[100][100];void welfol(int n){ d[0][0]=0; for(int i=1; i<=n; i++) { d[i][i]=1; d[0][i]=d[i][0]=1; } for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) { if(i==j)continue; int f=1; for(int k=1; f&&k<i; k++) if(d[i-k][j]==0) { d[i][j]=1; f=0; } for(int k=1; f&&k<j; k++) if(d[i][j-k]==0) { d[i][j]=1; f=0; } for(int k=1; f&&k<min(i,j); k++) if(d[i-k][j-k]==0) { d[i][j]=1; f=0; } }}void show(int n){ printf(" "); for(int i=0; i<=n; i++) printf("%3d",i); printf("\n"); for(int i=0; i<=n; i++) { printf("%3d",i); for(int j=0; j<=n; j++) printf("%3d",d[i][j]); printf("\n"); }}int main(){ welfol(20); show(20); return 0;}
递归版:
#include <iostream>#include <cstdio>#include <cstring>using namespace std;int ans[100][100];int solve(int m,int n){ if(m==0&&n==0) return 0; if(m==0||n==0) return 1; if(m==n) return 1; if(ans[m][n]!=-1) return ans[m][n]; for(int i=1;i<=m;i++) { ans[m-i][n]=solve(m-i,n); if(ans[m-i][n]==0) return 1; } for(int i=1;i<=n;i++) { ans[m][n-i]=solve(m,n-i); if(ans[m][n-i]==0) return 1; } for(int i=1;i<=min(m,n);i++) if(solve(m-i,n-i)==0) return 1; return 0;}int main(){ memset(ans,-1,sizeof(ans)); ans[0][0]=0; solve(23,22); printf(" "); for(int i=0;i<20;i++) printf("%2d ",i); printf("\n"); for(int i=0; i<20; i++) { printf("%2d ",i); for(int j=0; j<20; j++) printf("%d ",ans[i][j]); printf("\n"); } return 0;}运行结果如下:
由上图可知:
前几个必败点如下:(0,0),(1,2),(3,5),(4,7),(6,10),(8,13)……可以发现,对于第k个必败点(m(k),n(k))来说,m(k)是前面没有出现过的最小自然数,n(k)=m(k)+k。
判断一个点是不是必败点的公式与黄金分割有关。严格的推导,请读者自己证明。
m(k) = k * (1 + sqrt(5))/2
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std;#define GOLDEN 1.6180339887498int main(){ int n,m,k; while(cin>>n>>m) { if(n<m)swap(n,m); k=n-m; k=(int)(k*(1.0+sqrt(5.0))/2); if(k==m) printf("0\n"); else printf("1\n"); } return 0;}
- hdu1527-威佐夫博弈(Wythoff Game)
- hdu1527威佐夫博奕(Wythoff Game)
- 威佐夫博弈(Wythoff Game)
- 威佐夫博弈(Wythoff Game)
- 威佐夫博弈(Wythoff Game)
- hdu-2177(威佐夫博弈。Wythoff Game)
- Wythoff’s Game (威佐夫博弈)
- 博弈---威佐夫博奕(Wythoff Game)
- hdu1527,poj1067 取石子游戏 威佐夫博奕(Wythoff Game)
- 威佐夫(Wythoff)博弈
- EP6: Wythoff’s Game (威佐夫博弈)
- EP6: Wythoff’s Game (威佐夫博弈)
- 理论: 博弈4 :威佐夫博奕(Wythoff Game)
- 取石子游戏(hdu1527+威佐夫博弈)
- 【HDU1527】取石子游戏(威佐夫博弈)
- hdu1527 威佐夫博弈
- 威佐夫博弈->HDU1527
- hdu1527(博弈问题)
- SQL Union和SQL Union All用法
- unity3D之克隆游戏对象
- 使用Ajax发送Struts2请求返回JSON数据格式
- SICP学习 - 序
- 数据结构multiset hdu-2275-Kiki & Little Kiki 1
- hdu1527-威佐夫博弈(Wythoff Game)
- C#用Oledb查询Excel某个sheet中的数据——按多个条件查询
- Linux开机启动服务设置
- IT学生解惑真经
- redhat5安装jdk6、eclipse和tomcat6
- 按位运算符(>> << ~ & ^ | )及实例
- 自学java总结----equals
- jquery fullCalendar 显示时出现12a的解决方案
- Python 字典