题意:

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

输出分为几种。

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. Visual C++ 经常使用快捷键

    大写和小写 Ctrl+Shift+U: 所有变为大写 Ctrl+U: 所有变为小写 凝视 Ctrl+K+Crtr+C: 凝视选定内容  Ctrl+K+Crtr+U: 取消选定凝视内容 折叠 折叠代码: ...

  2. unity3d 中动画的帧事件

    代码事件监听 using UnityEngine; using System.Collections; public class BoxEventScript : MonoBehaviour { vo ...

  3. LeetCode题解 || Longest Substring Without Repeating Characters (O(n)算法)问题

    problem: Given a string, find the length of the longest substring without repeating characters. For ...

  4. c# DataTable to Object Mapping

    public static class DataTableExtensions { public static IList<T> ToList<T>(this DataTabl ...

  5. 使用神经网络-垃圾邮件检测-LSTM或者CNN(一维卷积)效果都不错【代码有问题,pass】

    from sklearn.feature_extraction.text import CountVectorizer import os from sklearn.naive_bayes impor ...

  6. linux 下Redis 5.0主从复制(一主二从)哨兵模式的搭建

    文档结构如下: 一.环境说明: 作用 IP地址 端口 操作系统版本 安装目录 哨兵文件 主库 172.16.10.80 6379 Redhat 6.7 /redis5.0/redis-5.0.0 Se ...

  7. sdwebimage缓存图片

    当使用SDWebImage时,如果用相同图片名的图片替换掉了原始缓存的图片,当再次请求的时候,还是使用的缓存图片,图片不会发生改变 原因:图片在NSCache中是以absolute url作为key存 ...

  8. 50个极好的bootstrap 后台框架主题下载

    50个极好的bootstrap 后台框架主题下载 http://sudasuta.com/bootstrap-admin-templates.html 越来越多的设计师和前端工程师开始用bootstr ...

  9. Spring学习笔记(一) 简介

    版权声明 本文是摘自IBM上Naveen Balani的一篇文章,原文请点击此处:http://www.ibm.com/developerworks/cn/java/wa-spring1/ Sprin ...

  10. Load和CPU利用率是如何算出来的

    相信很多人都对Linux中top命令里“load average”这一栏困惑过,到底什么是Load,Load代表了什么含义,Load高会有什么后果?“%CPU”这一栏为什么会超过100%,它是如何计算 ...