hdu 2177 取(2堆)石子游戏(威佐夫博奕)
题目链接:hdu 2177
这题不是普通的 Nim 博弈,我想它应该是另一种博弈吧,于是便推 sg 函数打了个 20*20 的表来看,为了方便看一些,我用颜色作了标记,打表代码如下:
#include<cstdio>
#include<cstring>
#include<string>
#include<map>
#include<algorithm>
#include<windows.h>
using namespace std; int sg[][]; int dfs(int i, int j) {
if(i > j) swap(i,j);
if(sg[i][j] != - || sg[j][i] != -)
return sg[j][i] = sg[i][j]; bool *vis = new bool[];
for(int g = ; g < ; ++g)
vis[g] = ; for(int x = ; x <= i; ++x)
vis[dfs(i - x, j)] = vis[dfs(i - x, j - x)] = ;
for(int y = ; y <= j; ++y)
vis[dfs(i, j - y)] = ; for(int g = ; ; ++g) {
if(!vis[g]) {
delete[] vis;
return sg[j][i] = sg[i][j] = g;
}
}
} map<string, WORD> m;
inline void init() {
m["blue"] = | FOREGROUND_INTENSITY;
m["green"] = | FOREGROUND_INTENSITY;
m["cyan"] = | FOREGROUND_INTENSITY;
m["red"] = | FOREGROUND_INTENSITY;
m["pink"] = | FOREGROUND_INTENSITY;
m["yellow"] = | FOREGROUND_INTENSITY;
m["white"] = | FOREGROUND_INTENSITY;
} HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); inline void setColor(const string &color) {
SetConsoleTextAttribute(hConsole, m[color]);
} int main() {
int a,b;
memset(sg, -, sizeof sg);
sg[][] = ; init();
printf(" ");
setColor("yellow");
for(int i = ; i <= ; ++i)
printf("%2d ",i);
puts("");
for(int i = ; i <= ; ++i) {
setColor("yellow");
printf("%2d ",i);
for(int j = ; j <= ; ++j) {
if(dfs(i,j) == ) setColor("red");
else setColor("white");
printf("%2d ", dfs(i,j));
}
puts("");
} puts("");
setColor("cyan");
for(int i = ; i <= ; ++i)
for(int j = i; j <= ; ++j)
if(dfs(i,j) == ) printf("%d %d\n",i,j);
setColor("white"); return ;
}
运行结果如下:
看不出有什么规律,逐百度之,发现原来是威佐夫博奕,最后判定时需要用到黄金分割数什么的,不过是 O(1) 的复杂度,但杭电这道题还要输出第 1 步操作后的结果,也就是还要模拟一下,不知道它的数据量有多少,觉得直接暴力枚举应该会超时吧,便想写个二分,可是写了好久越写越乱,于是干脆试下暴力,竟然秒过了,后台数据估计少得可怜。需要输出的答案最多不会超过 3 组,但为了方便,我还是用 vector 来存下了符合要求的答案:
#include<cstdio>
#include<cmath>
#include<set>
#include<vector>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int N = ;
const double p = (sqrt(5.0) + ) / ; bool ok(int a, int b) {
if(a > b) swap(a,b);
int k = b - a;
int c = int(k * p);
return c == a;
} int main() {
int a,b;
while(~scanf("%d %d",&a,&b),a) {
if(a > b) swap(a,b);
if(ok(a,b)) puts("");
else {
puts("");
for(int i = ; i < a; ++i)
if(ok(a - i, b - i)) printf("%d %d\n", a - i, b - i);
vector<pair<int,int> > v;
for(int i = ; i < a; ++i)
if(ok(a - i, b)) v.push_back(make_pair(a - i, b));
for(int i = ; i < b; ++i)
if(ok(a, b - i)) {
if(a > b - i) v.push_back(make_pair(b - i, a));
else v.push_back(make_pair(a, b - i));
}
sort(v.begin(), v.end());
int m = unique(v.begin(), v.end()) - v.begin();
for(int i = ; i < m; ++i)
printf("%d %d\n", v[i].first, v[i].second);
}
}
return ;
}
hdu 2177 取(2堆)石子游戏(威佐夫博奕)的更多相关文章
- HDU-2177 取(2堆)石子游戏 (威佐夫博奕)
Problem Description 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同 ...
- HDU 2177 取(2堆)石子游戏
取(2堆)石子游戏 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- HDU 2177 取(2堆)石子游戏 (威佐夫博弈)
题目思路:威佐夫博弈: 当当前局面[a,b]为奇异局时直接输出0 否则: 1.若a==b,输出(0 0): 2.将a,b不停减一,看能否得到奇异局,若有则输出: 3.由于 ak=q*k(q为黄金分割数 ...
- HDU2177:取(2堆)石子游戏(威佐夫博弈)
Problem Description 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同 ...
- poj 1067 取石子游戏( 威佐夫博奕)
题目:http://poj.org/problem?id=1067 题意:有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的 ...
- hdu 2177 取(2堆)石子游戏 博弈论
由于要输出方案,变得复杂了.数据不是很大,首先打表,所有whthoff 的奇异局势. 然后直接判断是否为必胜局面. 如果必胜,首先判断能否直接同时相减得到.这里不需要遍历或者二分查找.由于两者同时减去 ...
- HDU 2176 取(m堆)石子游戏(Nim)
取(m堆)石子游戏 题意: Problem Description m堆石子,两人轮流取.只能在1堆中取.取完者胜.先取者负输出No.先取者胜输出Yes,然后输出怎样取子.例如5堆 5,7,8,9,1 ...
- HDU 2176:取(m堆)石子游戏(Nim博弈)
取(m堆)石子游戏 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...
- HDU 2176 取(m堆)石子游戏 (尼姆博奕)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2176 m堆石子,两人轮流取.只能在1堆中取.取完者胜.先取者负输出No.先取者胜输出Yes,然后输出怎 ...
随机推荐
- ERROR 2006 (HY000) at line xx: MySQL server has gone away 解决方法
- iOS 数组内中英文混合排序
NSInteger sortObjects(id obj1, id obj2,void *context) { NSMutableString * str1 = [[NSMutableString a ...
- ftp列表错误或长城宽带连不上ftp的解决方法
有些是长城宽带,我 帮忙测试,在客户PC机上测试,PING 任何网站 不通:tracert 超时:FTP 超时,不出现用户名提示.但访问网站正常,检测后进入到路由器,禁用DHCP服务 ,问题解决. 或 ...
- 创建一个程序,从应用程序中随机添加N名参加歌唱比赛的同学,并随机对这N名同学的比赛按姓名的拼音先后顺序进行排序
public class Pint { /** * 姓名 */ public String name; /** * 年龄 */ public String age; public Pint(){ } ...
- RabbitMQ学习总结 第三篇:工作队列Work Queue
目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...
- python的paramiko源码修改了一下,写了个操作命令的日志审计 bug修改
python的paramiko源码修改了一下,写了个操作命令的日志审计,但是记录的日志中也将backspace删除键记录成^H这个了,于是改了一下代码,用字符串的特性. 字符串具有列表的特性 > ...
- 转:"在已损坏了程序内部状态的XXX.exe 中发生了缓冲区溢出"的一种可能原因
我的问题跟原作者的问题差不多.头文件和DLL不匹配导致的. 原文链接:http://blog.csdn.net/u012494876/article/details/39030887 今天软件突然出现 ...
- 网站和Web应用程序的区别
新建项目里面的(ASP.NET Web 应用程序)主要是做B/S系统的,与winform的开发方式类似.新建网站(ASP.NET 网站)是主要开发网站的.其实你只要跟着教程做就行了.具体区别如下(借鉴 ...
- Winform 主窗体更换 构造函数传值
制作登录窗体: 制作一个登陆窗体,实现点击按钮关闭此窗体并打开另一个窗体 直接在按钮点击事件中,实例化一个想要打开的窗体 使用show方法打开,并把登陆窗体的visible属性改为false Form ...
- opencv的学习笔记4
通常更加高级的形态学变换,如开闭运算.形态学梯度.“顶帽”.“黑帽”等等,都是可以由常用的腐蚀膨胀技术结合来达到想要的效果. 1.开运算:先腐蚀后膨胀,用于用来消除小物体.在纤细点处分离物体.平滑较大 ...