Find the Winning Move
Time Limit: 3000MS   Memory Limit: 32768K
Total Submissions: 1286   Accepted: 626

Description

4x4 tic-tac-toe is played on a board with four rows (numbered 0 to 3 from top to bottom) and four columns (numbered 0 to 3 from left to right). There are two players, x and o, who move alternately with x always going first. The game is won by the first player to get four of his or her pieces on the same row, column, or diagonal. If the board is full and neither player has won then the game is a draw. 
Assuming that it is x's turn to move, x is said to have a forced win if x can make a move such that no matter what moves o makes for the rest of the game, x can win. This does not necessarily mean that x will win on the very next move, although that is a possibility. It means that x has a winning strategy that will guarantee an eventual victory regardless of what o does.

Your job is to write a program that, given a partially-completed game with x to move next, will determine whether x has a forced win. You can assume that each player has made at least two moves, that the game has not already been won by either player, and that the board is not full.

Input

The input contains one or more test cases, followed by a line beginning with a dollar sign that signals the end of the file. Each test case begins with a line containing a question mark and is followed by four lines representing the board; formatting is exactly as shown in the example. The characters used in a board description are the period (representing an empty space), lowercase x, and lowercase o. For each test case, output a line containing the (row, column) position of the first forced win for x, or '#####' if there is no forced win. Format the output exactly as shown in the example.

Output

For this problem, the first forced win is determined by board position, not the number of moves required for victory. Search for a forced win by examining positions (0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), ..., (3, 2), (3, 3), in that order, and output the first forced win you find. In the second test case below, note that x could win immediately by playing at (0, 3) or (2, 0), but playing at (0, 1) will still ensure victory (although it unnecessarily delays it), and position (0, 1) comes first.

Sample Input

?
....
.xo.
.ox.
....
?
o...
.ox.
.xxx
xooo
$

Sample Output

#####
(0,1)

Source

 

#include<cstdio>
using namespace std;
char s[][];
int chess,X,Y;
inline int abs(int x){return x>?x:-x;}
bool check(int x,int y){//判断一个局面是否结束
int tot=;
for(int i=;i<;i++) s[x][i]=='o'?tot++:s[x][i]=='x'?tot--:tot;//横向判断
if(abs(tot)==) return ;tot=;
for(int i=;i<;i++) s[i][y]=='o'?tot++:s[i][y]=='x'?tot--:tot;//纵向判断
if(abs(tot)==) return ;tot=;
for(int i=;i<;i++) s[i][i]=='o'?tot++:s[i][i]=='x'?tot--:tot;//正对角线判断
if(abs(tot)==) return ;tot=;
for(int i=;i<;i++) s[i][-i]=='o'?tot++:s[i][-i]=='x'?tot--:tot;//反对角线判断
if(abs(tot)==) return ;
return ;
}
int Min(int ,int);
int Max(int ,int);
int Max(int x,int y){
if(check(x,y)) return -;//已经结束(对方胜)
if(chess==) return ;//平局
for(int i=,now;i<;i++){
for(int j=;j<;j++){
if(s[i][j]=='.'){
s[i][j]='x';chess++;
now=Min(i,j);
s[i][j]='.';chess--;
//对方需要找的最差估价,如果当前比之前最差的高,α剪枝
if(now==) return ;
}
}
}
return -;
}
int Min(int x,int y){
if(check(x,y)) return ;//已经结束(己方胜)
if(chess==) return ;
for(int i=,now;i<;i++){
for(int j=;j<;j++){
if(s[i][j]=='.'){
s[i][j]='o';chess++;
now=Max(i,j);
s[i][j]='.';chess--;
//自己需要找的最高估价,如果当前比之前最差的低,β剪枝
if(!now||now==-) return -;
}
}
}
return ;
}
bool solve(){
for(int i=,now;i<;i++){
for(int j=;j<;j++){//枚举,然后搜索
if(s[i][j]=='.'){
s[i][j]='x';chess++;
now=Min(i,j);
s[i][j]='.';chess--;
if(now==){
X=i;Y=j;
return ;
}
}
}
}
return ;
}
int main(){
char ch[];
while(~scanf("%s",ch)&&ch[]=='?'){
for(int i=;i<;i++) scanf("%s",s[i]);chess=;
for(int i=;i<;i++) for(int j=;j<;j++) chess+=s[i][j]!='.';
if(chess<=){puts("#####");continue;}//一定平局(对方都绝顶聪明的话)
if(solve()) printf("(%d,%d)\n",X,Y);
else puts("#####");
}
return ;
}

poj1568 Find the Winning Move[极大极小搜索+alpha-beta剪枝]的更多相关文章

  1. poj 1568 Find the Winning Move 极大极小搜索

    思路:用极大极小搜索解决这样的问题很方便!! 代码如下: #include <cstdio> #include <algorithm> #define inf 10000000 ...

  2. 算法笔记--极大极小搜索及alpha-beta剪枝

    参考1:https://www.zhihu.com/question/27221568 参考2:https://blog.csdn.net/hzk_cpp/article/details/792757 ...

  3. 新手立体四子棋AI教程(3)——极值搜索与Alpha-Beta剪枝

    上一篇我们讲了评估函数,这一篇我们来讲讲立体四子棋的搜索函数. 一.极值搜索 极值搜索是game playing领域里非常经典的算法,它使用深度优先搜索(因为限制最大层数,所以也可以称为迭代加深搜索) ...

  4. 【poj1568】 Find the Winning Move

    http://poj.org/problem?id=1568 (题目链接) 题意 两人下4*4的井字棋,给出一个残局,问是否有先手必胜策略. Solution 极大极小搜索.. 这里有个强力优化,若已 ...

  5. 【迭代博弈+搜索+剪枝】poj-1568--Find the Winning Move

    poj  1568:Find the Winning Move   [迭代博弈+搜索+剪枝] 题面省略... Input The input contains one or more test cas ...

  6. POJ 1568 Find the Winning Move

    Find the Winning Move 链接 题意: 4*4的棋盘,给出一个初始局面,问先手有没有必胜策略? 有的话输出第一步下在哪里,如果有多个,按(0, 0), (0, 1), (0, 2), ...

  7. 极大极小搜索思想+(α/β)减枝 【转自-----https://blog.csdn.net/hzk_cpp/article/details/79275772】

    极大极小搜索,即minimax搜索算法,专门用来做博弈论的问题的暴力. 多被称为对抗搜索算法. 这个搜索算法的基本思想就是分两层,一层是先手,记为a,还有一层是后手,记为b. 这个搜索是认为这a与b的 ...

  8. POJ 1568 极大极小搜索 + alpha-beta剪枝

    极小极大搜索 的个人理解(alpha-beta剪枝) 主要算法依据就是根据极大极小搜索实现的. 苦逼的是,查了两个晚上的错,原来最终是判断函数写错了..瞬间吐血! ps. 据说加一句 if sum & ...

  9. [CodeVs3196]黄金宝藏(DP/极大极小搜索)

    题目大意:给出n(≤500)个数,两个人轮流取数,每次可以从数列左边或者右边取一个数,直到所有的数被取完,两个人都以最优策略取数,求最后两人所得分数. 显然这种类型的博弈题,第一眼就是极大极小搜索+记 ...

随机推荐

  1. LPD打印机服务是什么意思

    line Printer Daemon(LPD)行式打印机后台程序,用于假脱机打印工作的UNIX后台程序(后台服务).行式打印机后台程序是一个安装在UNIX打印服务器上的后台程序.它的功能是等待接受客 ...

  2. Windows Server 2008组策略安全实践(同样适用于域控制)

    Windows Server 2008系统的安全功能非法强大,而它的强大之处不仅仅是新增加了一些安全功能,而且还表现在一些不起眼的传统功能上.对Windows Server 2008系统的组策略功能进 ...

  3. 文件服务器和web应用分离的思路(转)

    目前在做一个应用,有不同的客户端,包括web应用的客户端,其他的客户端,都要访问我的文件服务器,通过文件服务程序提供的服务来访问文件,但是对文件管理服务器这个应用,没有什么思路,请大家给点思路,谢谢: ...

  4. ORACLE11G 字符集更改(这里更改为AL32UTF8)

    ORACLE11G 字符集更改(这里更改为AL32UTF8)更改步骤:1.用sysdba角色用户登录sqlplus: 命令行输入:sqlplus sys as sysdba 2.输入口令,进入sqlp ...

  5. spring mvc 下载安装

    https://repo.spring.io/webapp/#/artifacts/browse/tree/General/libs-release-local/org/springframework ...

  6. MFC 无边框窗体实现用鼠标拖动窗体边缘实现窗体大小变化

    无边框窗体如何实现用鼠标拖动窗体边缘实现窗体大小变动呢?下面介绍一种方法,通过以下几个步骤即可实现: 1.实现WM_NCHITTEST消息,实现四条边框的模拟 2.实现WM_NCLBUTTONDOWN ...

  7. 网络协议之bt---bt协议详解 DHT篇(下)

    -------------------------author:pkf -------------------------------qq:1327706646 ------------------- ...

  8. Nginx配置PATHINFO隐藏index.php

    1.网络来源:http://www.shouce.ren/post/view/id/1529 server {      listen       80;     default_type text/ ...

  9. PHP中替换换行符方法总结

    <?php header("content-type:text/html;charset=utf-8"); $str = "aaaa bbbb cccc dddd& ...

  10. 大型web系统数据缓存设计-l转载

    原文地址:http://www.wmyouxi.com/a/60368.html#ixzz3tGYG9JwC 1. 前言 在高访问量的web系统中,缓存几乎是离不开的:但是一个适当.高效的缓存方案设计 ...