题意:

两个人下五子棋。给你现有棋盘,推断在三步之内的胜负情况。

输出分为几种。

1、棋盘不合法

2、黑或白在第一步赢下在(x,y)点,多个输出x最小的、y最小的。

3、输在第二步

4、黑或白在第三步赢在(x,y)点,多个输出x最小的、y最小的。

5、三步内不分胜负

思路:

首先先推断棋盘是否合法

然后就是须要一个寻找当前我要下黑棋或者白棋在棋盘中我有几个必胜点。

所谓的必胜点就是我下这个位置我能连五子或者以上。

然后就是

1、一步直接赢(我有一个或以上的必胜点)

2、二步直接输(对方有两个以上的必胜点)

3、对方有且仅仅有一个必胜点(我第一步堵上对方的必胜点。然后看我有没有2个必胜点,有我三步胜,没有三步内不分胜负)

4、枚举我能够下的每个点,看看下完我有没有两个必胜点,有的话三步赢。没有的话三步内不分胜负。

代码:

#include"cstdlib"
#include"cstdio"
#include"cstring"
#include"cmath"
#include"queue"
#include"algorithm"
#include"iostream"
using namespace std;
int map[22][22];
int move[8][2]= {{0,-1},{-1,-1},{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1}};
int n;
struct winpoint
{
int cnt,x,y;
winpoint()
{
cnt=x=y=0;
}
};
int dfs(int x,int y,int f,int key)
{
int xx=x,yy=y;
int sum=0;
while(1)
{
sum++;
xx+=move[f][0];
yy+=move[f][1];
if(xx<0||yy<0||xx>=15||yy>=15) break;
if(map[xx][yy]!=key) break;
}
return sum;
}
winpoint ok1(int key)
{
winpoint ans;
for(int i=0; i<15; i++)
{
for(int j=0; j<15; j++)
{
if(map[i][j]!=-1) continue;
int f=0;
for(int k=0; k<4; k++)
{
if(dfs(i,j,k,key)+dfs(i,j,k+4,key)-1>=5) f=1;
if(f) break;
}
if(f)
{
if(ans.cnt==0)
{
ans.x=i;
ans.y=j;
}
ans.cnt++;
}
}
}
return ans;
}
int main()
{
while(scanf("%d",&n),n)
{
memset(map,-1,sizeof(map));
int f=-1;
int bl,wh;
bl=wh=0;
while(n--)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
map[x][y]=z;
if(z) bl++;
else wh++;
}
if(bl<wh||bl>=wh+2) //不合法
{
puts("Invalid.");
continue;
}
int key;
if(bl==wh) key=1;
else key=0;
winpoint ans;
ans=ok1(key); if(ans.cnt>=1) //一步直接赢
{
printf("%s",key? "Place black ":"Place white ");
printf("at (%d,%d) to win in 1 move.\n",ans.x,ans.y);
continue;
}
ans=ok1(key^1);
if(ans.cnt>=2) //两个必胜点 直接输
{
puts("Lose in 2 moves.");
continue;
}
if(ans.cnt==1) //填对方必胜点 看是否能赢
{
map[ans.x][ans.y]=key;
winpoint tep=ok1(key);
if(tep.cnt>=2) //对方堵不住 直接赢
{
printf("%s",key?"Place black ":"Place white ");
printf("at (%d,%d) to win in 3 moves.\n",ans.x,ans.y);
continue;
}
else //不能则不分胜负
{
puts("Cannot win in 3 moves.");
continue;
}
}
for(int i=0; i<15; i++) //枚举每一个点
{
for(int j=0; j<15; j++)
{
if(map[i][j]!=-1) continue;
map[i][j]=key;
winpoint tep=ok1(key);
if(tep.cnt>=2)
{
printf("%s",key? "Place black ":"Place white ");
printf("at (%d,%d) to win in 3 moves.\n",i,j);
f=1;
}
if(f==1) break;
map[i][j]=-1;
}
if(f==1) break;
}
if(f==-1) puts("Cannot win in 3 moves.");
}
return 0;
}

[博弈] hdu 3683 Gomoku的更多相关文章

  1. hdu 3683 Gomoku (模拟、搜索)

    Gomoku Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Sub ...

  2. HDU 3683 模拟&amp;搜索

    给出五子棋残局,推断三步内能否分出胜负,玩家为当前该走旗子的颜色,下一步为白棋或黑棋不定. 依照顺序推断就可以: 1:推断棋盘是否合法,并确定玩家颜色 2:推断当前玩家颜色是否有一个必胜点,有玩家则在 ...

  3. HDU题解索引

    HDU 1000 A + B Problem  I/O HDU 1001 Sum Problem  数学 HDU 1002 A + B Problem II  高精度加法 HDU 1003 Maxsu ...

  4. HDU 2509 Nim博弈变形

    1.HDU 2509  2.题意:n堆苹果,两个人轮流,每次从一堆中取连续的多个,至少取一个,最后取光者败. 3.总结:Nim博弈的变形,还是不知道怎么分析,,,,看了大牛的博客. 传送门 首先给出结 ...

  5. HDU 1907 Nim博弈变形

    1.HDU 1907 2.题意:n堆糖,两人轮流,每次从任意一堆中至少取一个,最后取光者输. 3.总结:有点变形的Nim,还是不太明白,盗用一下学长的分析吧 传送门 分析:经典的Nim博弈的一点变形. ...

  6. HDU 5973 Game of Taking Stones 威佐夫博弈+大数

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5973 Game of Taking Stones Time Limit: 2000/1000 MS ...

  7. HDU 4315:Climbing the Hill(阶梯博弈)

    http://acm.hdu.edu.cn/showproblem.php?pid=4315 题意:有n个人要往坐标为0的地方移动,他们分别有一个位置a[i],其中最靠近0的第k个人是king,移动的 ...

  8. HDU 5996:dingyeye loves stone(阶梯博弈)

    http://acm.hdu.edu.cn/showproblem.php?pid=5996 题意:在一棵树上进行博弈,每次只能将当前的结点的石子放到父节点上,最后不能移动的输. 思路:比赛的时候想的 ...

  9. HDU 5795 A Simple Nim (博弈 打表找规律)

    A Simple Nim 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5795 Description Two players take turns ...

随机推荐

  1. 具体解释Redis源代码中的部分高速排序算法(pqsort.c)

    看标题.你可能会疑惑:咦?你这家伙.怎么不解说完整的快排,仅仅讲一部分快排---.- 哎,冤枉. "部分快排"是算法的名字.实际上本文相当具体呢.本文差点儿与普通快排无异.看懂了本 ...

  2. json 与其他数据 格式转换及json学习新得

    jsonobject   var a={"a","A"}   通过json都对象能很轻松的操作json数据 jsonString     var a=" ...

  3. JMX学习笔记(一)-MBean

    JMX学习笔记(一)-MBean 标签: jmxstringjavainterfaceexceptionclass 2010-12-07 22:20 15360人阅读 评论(5) 收藏 举报  分类: ...

  4. codecombat之边远地区的森林1-11关及地牢38关代码分享

    codecombat中国游戏网址:http://www.codecombat.cn/ 全部代码为javascript代码分享 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ...

  5. Caffe_Example之训练mnist

    0.参考文献 [1]caffe官网<Training LeNet on MNIST with Caffe>; [2]薛开宇<读书笔记4学习搭建自己的网络MNIST在caffe上进行训 ...

  6. Spark RDD概念学习系列之RDD接口

    不多说,直接上干货!

  7. 洛谷P4014 分配问题(费用流)

    题目描述 有 nn 件工作要分配给 nn 个人做.第 ii 个人做第 jj 件工作产生的效益为 c_{ij}cij​ .试设计一个将 nn 件工作分配给 nn 个人做的分配方案,使产生的总效益最大. ...

  8. java中不同类如何相互访问变量值(新手见解,可能很low)

    最近在学基础java知识,这个是很常见的问题之一了,下面我要列出三种异类取值方法,当然不止这些,我选择了最简单的三种: 1.可以使用static静态变量,直接调用要访问类的属性和方法.因为 Java ...

  9. Sybase to Oracle Golden Gate

    Sybase 安装Golden Gate: 下载,然后create subdirs.并且在两端配置好mgr,设置好端口7809 创建golden gate用户ogguser,并且给它授权sa和repl ...

  10. SQL Server-简单查询语句,疑惑篇

      前言 对于一些原理性文章园中已有大量的文章尤其是关于索引这一块,我也是花费大量时间去学习,对于了解索引原理对于后续理解查询计划和性能调优有很大的帮助,而我们只是一些内容进行概括和总结,这一节我们开 ...