巴氏(bash)威佐夫(Wythoff)尼姆(Nim)博弈之模板
2014-11-01 13:40
501 查看
最近研究了一下博弈论(听起来很高大上),当然,这只是博弈论中的冰山一角,但不可否认,巴氏(bash)博弈,威佐夫(Wythoff)博弈和尼姆(Nim)博弈这三种在ACM比赛中也是相当重要的,而最大的问题就是,博弈理解起来有较大的难度,即使理解了,也很难快速转换成代码,这对于做题来说是很不利的,于是,我就决定写一套模板,包括多一点接口,从而方便以后的使用,当然,虽然说是自己写的,但也是参考了别人的代码,所以别告我侵权哈。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/899229cfab2c02d614490485cabb781b.gif)
首先是Bash(巴氏)博弈,这是比较简单的一种,原理就不解释了,相信大家都懂,代码很简短,只需要输入这一堆石子的数目,输赢立刻见分晓
#include<iostream>
using namespace std;
int main(void)
{
int cas,total,price;
scanf("%d",&cas);
while(cas--)
{
scanf("%d%d",&total,&price);
if(total%(price+1))
cout<<"先手赢"<<endl;
else
cout<<"先手输"<<endl;
}
return 0;
} 接下来上威佐夫(Wythoff)博弈,石子变成两堆,难度也大幅提升,但是
我擦,为毛代码还是这么短
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/panic.gif)
,大神膜拜中。。。(过奖过奖
![](https://oscdn.geek-share.com/Uploads/Images/Content/201706/4ea38101608645b64e3ba76e93a6ce02.gif)
,如有雷同,请相信这真的只是借鉴)
最后奉上尼姆(Nim)博弈,这种博弈其实就是分解成简单的博弈再一一求解
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;
int a[200005],ans[200005][2];
int main()
{
int n,i,j,cnt,s;
while(~scanf("%d",&n),n)
{
cnt = 0;
s = 0;
for(i = 0; i<n; i++)
{
scanf("%d",&a[i]);
s^=a[i];
}
for(i = 0; i<n; i++)
{
if(a[i] > (s^a[i]))
{
ans[cnt][0] = a[i];
ans[cnt][1] = s^a[i];
cnt++;
}
}
if(cnt)//判断先手是胜是负
{
printf("Yes\n");
for(i = 0; i<cnt; i++)
printf("%d %d\n",ans[i][0],ans[i][1]);//输出若先手为胜的走法
}
else
printf("No\n");
cout<<cnt<<endl;//输出使先手为胜的方案的数目
}
return 0;
}
这个稍微长一点,因为里面增加了很多步骤,大大方便了题目的求解。
从今天开始,你就可以骄(zhuang)傲(bi)的说:“今朝获此三模板,从此博弈是水题!”
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/899229cfab2c02d614490485cabb781b.gif)
首先是Bash(巴氏)博弈,这是比较简单的一种,原理就不解释了,相信大家都懂,代码很简短,只需要输入这一堆石子的数目,输赢立刻见分晓
#include<iostream>
using namespace std;
int main(void)
{
int cas,total,price;
scanf("%d",&cas);
while(cas--)
{
scanf("%d%d",&total,&price);
if(total%(price+1))
cout<<"先手赢"<<endl;
else
cout<<"先手输"<<endl;
}
return 0;
} 接下来上威佐夫(Wythoff)博弈,石子变成两堆,难度也大幅提升,但是
#include<iostream> #include<cmath> #include<stdio.h> using namespace std; int main () { int a,b,dif; double p=(sqrt((double)5)+1)/double(2); while(cin>>a>>b) { dif=abs(a-b);//取差值 a=a<b?a:b;//取较小的值 if(a==(int)(p*dif))//判断是不是奇异局势 printf("0\n"); else printf("1\n"); } return 0; }
我擦,为毛代码还是这么短
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/panic.gif)
,大神膜拜中。。。(过奖过奖
![](https://oscdn.geek-share.com/Uploads/Images/Content/201706/4ea38101608645b64e3ba76e93a6ce02.gif)
,如有雷同,请相信这真的只是借鉴)
最后奉上尼姆(Nim)博弈,这种博弈其实就是分解成简单的博弈再一一求解
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;
int a[200005],ans[200005][2];
int main()
{
int n,i,j,cnt,s;
while(~scanf("%d",&n),n)
{
cnt = 0;
s = 0;
for(i = 0; i<n; i++)
{
scanf("%d",&a[i]);
s^=a[i];
}
for(i = 0; i<n; i++)
{
if(a[i] > (s^a[i]))
{
ans[cnt][0] = a[i];
ans[cnt][1] = s^a[i];
cnt++;
}
}
if(cnt)//判断先手是胜是负
{
printf("Yes\n");
for(i = 0; i<cnt; i++)
printf("%d %d\n",ans[i][0],ans[i][1]);//输出若先手为胜的走法
}
else
printf("No\n");
cout<<cnt<<endl;//输出使先手为胜的方案的数目
}
return 0;
}
这个稍微长一点,因为里面增加了很多步骤,大大方便了题目的求解。
从今天开始,你就可以骄(zhuang)傲(bi)的说:“今朝获此三模板,从此博弈是水题!”
相关文章推荐
- 巴氏(bash)威佐夫(Wythoff)尼姆(Nim)博弈之模板
- 巴氏(bash)威佐夫(Wythoff)尼姆(Nim)博弈之模板
- (转)巴氏(bash)威佐夫(Wythoff)尼姆(Nim)博弈之模板
- 博弈模板(bash,威佐夫,Nim)
- 博弈论模板(巴什博奕,威佐夫博弈,尼姆博弈,斐波那契博弈)
- Return of the Nim----Nim博弈+威佐夫博弈 山东省第八届省赛A题
- poj1067 威佐夫博弈模板 取石子游戏
- 51NOD 1068 Bash游戏 V3 (大数模板套用) 博弈
- 巴什博弈、威佐夫博弈、尼姆博弈
- NIM游戏,NIM游戏变形,威佐夫博弈以及巴什博奕总结
- HDU 1536 && HDU 1944 S-Nim (Nim博弈、SG函数模板)
- 威佐夫博弈(模板+减少精度算法)
- HDOJ 题目S-Nim(sg-博弈,模板)
- 巴什博弈 威佐夫博弈 nim博弈 斐波那契博弈
- 杭电1527 取石子游戏(威佐夫博弈模板)
- 威佐夫(Wythoff)博弈
- POJ2960 S-Nim (sg博弈模板)
- poj 2975 Nim 尼姆博弈,求取胜方案数
- 博弈论(巴什博奕,威佐夫博弈,尼姆博弈,斐波那契博弈) (转载)
- HDU 1527 取石子游戏 威佐夫博弈 Wythoff