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,然后输出怎 ...
随机推荐
- Nginx 反向代理学习(一)
反向代理apache等http资源 ## Basic reverse proxy server ## upstream apachephp{ server 127.0.0.1:8560; #php5. ...
- Extjs 表格横坐标显示问题
在项目中显示chart时,当横坐标的标签名称过长时,extjs会自动隐藏部分的标签. 我想,如果能让标签斜着,或者纵向显示的话,就能够节省x轴上的长度. 经过在网上查找,解决方案如下. //在表格的a ...
- jq选中问题
var objs = $("div[id^='offer_details_']"); //遍历点击事件监听问题 onclick="details("+offer ...
- scrum3.0
3.0----------------------------------------------------- SCRUM 流程的步骤2: Spring 计划 1. 确保product backlo ...
- BAT脚本打印空行的使用方法
@echo off echo= echo, echo; echo+ echo/ echo[ echo] echo: echo. echo\ pause 这十种方法可以分为三组,每组的效率依次递减. 至 ...
- 夺命雷公狗-----React---1--页面的渲染
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Monkey之环境搭建完全版
图文版将在后期补充. 如果想要搭建好Monkey的测试环境,首先几个必要的步骤和环境不能少,分别是java相关环境.Android SDK环境,启动android虚拟机或连接真机.执行monkey测试 ...
- 使用 supervisor 管理进程
安装: # yum install python-setuptools # easy_install supervisor 如果已经安装了epel和python-pip, 也可以简单 pip inst ...
- SVN使用教程总结
SVN简介: 为什么要使用SVN? 程序员在编写程序的过程中,每个程序员都会生成很多不同的版本,这就需要程序员有效的管理代码,在需要的时候可以迅速,准确取出相应的版本. Subversion是什么? ...
- Upload file
<h3>Upload File</h3> <form action="@Url.Action("Upload","UploadCo ...