题意:

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

输出分为几种。

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. JAVAEE之--------过滤器设置是否缓存(Filter)

    在网页中.每次的client訪问server.有部分不用反复请求.如有些图片,视频等就没有必要每次都请求,这样会让server增大工作量.为了防止这样.我们採用过滤器来设置client是都缓存. 參考 ...

  2. android布局中显示隐藏动画

    android 在布局中提供属性,能简单的加入动画效果,例如以下: <LinearLayout ... animateLayoutChanges="true" ... /&g ...

  3. MySql 基础学习笔记 1——概述与基本数据类型: 整型: 1)TINYINT 2)SMALLINT 3) MEDIUMINT 4)INT 5)BIGINT 主要是大小的差别 图 浮点型:命令

    一.CMD中经常使用mysql相关命令 mysql -D, --database=name  //打开数据库 --delimiter=name  //指定分隔符 -h, --host=name  // ...

  4. js 回调函数小例子

    js 回调函数小例子 <script> //将函数作为另一个函数的参数 function test1(){ alert("我是test1"); } function t ...

  5. Linux就该这么学 20181011(第十五章邮件)

    参考链接:https://www.linuxprobe.com. https://www.linuxprobe.com/chapter-15.html 电子邮箱系统 foxmail MUA 发送 MT ...

  6. .NET中的异步操作及线程同步

    执行异步操作 CLR使用了WIN的线程处理能力,但保留了与其分离的权利.某些时候CLR的线程与Win的线程不是完全的匹配. 线程的系统开销较大,应限制其数量. 创建:分配并初始化一线程内核对象,保留1 ...

  7. android UI卡顿问题学习

    转自https://blog.csdn.net/joye123/article/details/79425398 https://blog.csdn.net/zhenjie_chang/article ...

  8. 记录sql执行顺序

    SQL 语句执行顺序为: FROM WHERE GROUP BY HAVING SELECT DISTINCT UNION ORDER BY 关于 SQL 语句的执行顺序,有三个值得我们注意的地方: ...

  9. addEventListener()与removeEventListener(),追加事件和删除追加事件

    addEventListener()与removeEventListener()用于追加事件和删除追加.所有的DOM节点中都包含这两种方法,并且它们都接受3个参数:要处理的事件名.作为事件处理程序的函 ...

  10. Hihocoder1458-Parentheses Matching(stack,vector)

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 Given a string of balanced parentheses output all the matchin ...