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. 【DataStructure】Linked Data Structures

    Arrayss work well for unordered sequences, and even for ordered squences if they don't change much. ...

  2. JS 播放列表收缩展开

    下面要做实现的效果 收缩和展的功能 遵循网页布局,行为,结构,样式 分离 下面是html 结构代码: <div id="drop" class="down_list ...

  3. 机器学习之梯度提升决策树GBDT

    集成学习总结 简单易学的机器学习算法——梯度提升决策树GBDT GBDT(Gradient Boosting Decision Tree) Boosted Tree:一篇很有见识的文章 https:/ ...

  4. 第三百二十一节,Django框架,发送邮件

    第三百二十一节,Django框架,发送邮件 全局配置settings.py EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' ...

  5. Xenocode Postbuild 2010 for .NET 混淆工具的详细使用步骤【转】

    1,首先我们需要去下载这个工具去,我这里倒是有一个下载的网址,已经被破解了,而且有序列号 http://download.csdn.net/tag/Xenocode+Postbuild+2010+fo ...

  6. linux -- Ubuntu Server 安装图形界面

    1.连接网络,你一定要确保网络通畅,如果你和我一样使用Wireless,那先找根网线插上,因为下面的安装都要通过网络下载组件的. 2.进入图形界面的命令是startX,敲击后会有安装xinit的提示. ...

  7. 转载:MochiWeb一些资料的链接

    转自:http://veniceweb.googlecode.com/svn/trunk/public/daily_tech_doc/mochiweb_20091030.txt MochiWeb项目主 ...

  8. LabVIEW中数组的自动索引

    我们在LabVIEW里面使用While或者是For循环结构的时候,就会发现每一个循环中在它们的循环结构的边界都可以自动完成一个数组元素的索引或累积.LabVIEW中循环结构的这种能力就叫做自动索引(A ...

  9. sublime text 删除插件

    1.ctrl+shift+p 输入remove package 选择要删掉的插件即可 2.去掉产生临死文件的插件:phptools

  10. c++ define的用法(转)

    #define是C语言中提供的宏定义命令,其主要目的是为程序员在编程时提供一定的方便,并能在一定程度上提高程序的运行效率,但学生在学习时往往不能 理解该命令的本质,总是在此处产生一些困惑,在编程时误用 ...