[博弈] hdu 3683 Gomoku
题意:
两个人下五子棋。给你现有棋盘,推断在三步之内的胜负情况。
输出分为几种。
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的更多相关文章
- hdu 3683 Gomoku (模拟、搜索)
Gomoku Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...
- HDU 3683 模拟&搜索
给出五子棋残局,推断三步内能否分出胜负,玩家为当前该走旗子的颜色,下一步为白棋或黑棋不定. 依照顺序推断就可以: 1:推断棋盘是否合法,并确定玩家颜色 2:推断当前玩家颜色是否有一个必胜点,有玩家则在 ...
- HDU题解索引
HDU 1000 A + B Problem I/O HDU 1001 Sum Problem 数学 HDU 1002 A + B Problem II 高精度加法 HDU 1003 Maxsu ...
- HDU 2509 Nim博弈变形
1.HDU 2509 2.题意:n堆苹果,两个人轮流,每次从一堆中取连续的多个,至少取一个,最后取光者败. 3.总结:Nim博弈的变形,还是不知道怎么分析,,,,看了大牛的博客. 传送门 首先给出结 ...
- HDU 1907 Nim博弈变形
1.HDU 1907 2.题意:n堆糖,两人轮流,每次从任意一堆中至少取一个,最后取光者输. 3.总结:有点变形的Nim,还是不太明白,盗用一下学长的分析吧 传送门 分析:经典的Nim博弈的一点变形. ...
- HDU 5973 Game of Taking Stones 威佐夫博弈+大数
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5973 Game of Taking Stones Time Limit: 2000/1000 MS ...
- HDU 4315:Climbing the Hill(阶梯博弈)
http://acm.hdu.edu.cn/showproblem.php?pid=4315 题意:有n个人要往坐标为0的地方移动,他们分别有一个位置a[i],其中最靠近0的第k个人是king,移动的 ...
- HDU 5996:dingyeye loves stone(阶梯博弈)
http://acm.hdu.edu.cn/showproblem.php?pid=5996 题意:在一棵树上进行博弈,每次只能将当前的结点的石子放到父节点上,最后不能移动的输. 思路:比赛的时候想的 ...
- HDU 5795 A Simple Nim (博弈 打表找规律)
A Simple Nim 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5795 Description Two players take turns ...
随机推荐
- 初学JavaScript之推測new操作符的原理
本文是一篇原理推測的文章,假设有不准确的地方请指正, 原文:http://blog.csdn.net/softmanfly/article/details/34833931 JavaScript中构造 ...
- 每天自己主动备份mysql脚本
定时运行脚本: 1.运行 crontab -e 00 00 * * * /bin/bash yourpath/mysqlbak.sh 2.打开自己主动运行文件 vi /etc/crontab 在etc ...
- SQL语法精讲(包括建库、建表、建视图、查询、增加、删除、)
SQL语法精讲(包括建库.建表.建视图.查询.增加.删除.修改) SQL分类: DDL—数据定义语言(CREATE,ALTER,DROP,DECLARE) DML—数据操纵语言(SELECT,DELE ...
- struts2在action中获取request、session、application,并传递数据
假设仅仅是通过request.session.application传递数据,则不须要获取对应的对象也能够传递数据,代码例如以下: ScopeAction.java: package com.ithe ...
- mysqli一些常用方法及详解
mysqli一些常用方法及详解 1.die()函数:表示向用户输出引号中的内容后,程序终止运行,提示定制的出错信息 ex: $conn = mysqli_connect("localhost ...
- xargs用例一个
ls -a *.doc|awk -F. '{print $1}' |xargs -I {} java -jar ~/soft/jodconverter-2.2.2/lib/jodconverter-c ...
- 通过QEMU-GuestAgent实现从外部注入写文件到KVM虚拟机内部
本文将以宿主上直接写文件到VM内部为例讲解为何要注入以及如何实现 tag: qemu-ga, qemu guest agent, kvm, guest-file-write, inject 小慢哥的原 ...
- Spark基本运行流程
不多说,直接上干货! Spark基本运行流程 Application program的组成 Job : 包含多个Task 组成的并行计算,跟Spark action对应. Stage : Job 的调 ...
- Android 自定义简单控件--星级评价
效果图 实现 package com.easypass.carstong.view; import android.content.Context; import android.content.re ...
- hdu 2795 Billboard 【线段树】
给出一个高为h,宽为w的广告板,有n张广告需要贴,从第一行开始贴,尽量靠左,输出每个广告最后贴在哪一行的 先一直想不通这样建树是为什么 后来看到一篇题解里面的一句话“直到找到一个满足条件的叶子节点” ...