【POJ1568】【极大极小搜索+alpha-beta剪枝】Find the Winning Move
Description
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
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
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 <set>
#include <map>
#include <cmath>
#include <cstdio>
#include <vector>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define LOCAL
const int MAXL = ;
const long long MOD = ;
const int MAXK = + ;
const int MAXN = + ;
const int MAXM = ;
const int INF = 0x7fffffff;
using namespace std;
char str[][];
int tot, X, Y;//代表棋子的数量 void init(){
tot = ;
for (int i = ; i <= ; i++){
scanf("%s", str[i] + );
for (int j = ; j <= ; j++) if (str[i][j] != '.') tot++;
}
/*for (int i = 1; i <= 4; i++){
for (int j = 1; j <= 4; j++)
printf("%c", str[i][j]);
printf("\n");
}*/
}
//判断是否达成胜利条件
bool check(int x, int y){
int num = ;//判断棋子的个数
for (int i = ;i <= ; i++){
//注意不要全部判断了
if (str[x][i] == 'o') num++;
else if (str[x][i] == 'x') num--;
}
if (num == || num == -) return ;
num = ;
for (int i = ; i <= ; i++){
if (str[i][y] == 'o') num++;
else if (str[i][y] == 'x') num--;
}
if (num == || num == -) return ;
num = ;
//判断主对角线
for (int i = ; i <= ; i++){
if (str[i][i] == 'o') num++;
else if (str[i][i] == 'x') num--;
}
if (num == || num == -) return ;
num = ;
for (int i = ; i <= ; i++){
if (str[i][ - i + ] == 'o') num++;
else if (str[i][ - i + ] == 'x') num--;
}
if (num == || num == -) return ;
return ;
}
int MaxSearch(int x, int y, int alpha);
int MinSearch(int x, int y, int beta); int MaxSearch(int x, int y, int alpha){
int Ans = -INF;
//最大获益
if (check(x, y)) return Ans;
if (tot == ) return ; for (int i = ; i <= ; i++)
for (int j = ; j <= ; j++){
if (str[i][j] != '.') continue;
str[i][j] = 'x';tot++;
int tmp = MinSearch(i, j, Ans);
str[i][j] = '.';tot--;
Ans = max(Ans, tmp);
if (Ans >= alpha) return Ans;
}
return Ans;
}
int MinSearch(int x, int y, int beta){
int Ans = INF;
//最小损失
if (check(x, y)) return Ans;
if (tot == ) return ;//平局 for (int i = ; i <= ; i++)
for (int j = ; j <= ; j++){
if (str[i][j] != '.') continue;
str[i][j] = 'o'; tot++;
int tmp = MaxSearch(i, j, Ans);
str[i][j] = '.'; tot--;
Ans = min(Ans , tmp);
if (Ans <= beta) return Ans;
}
return Ans;
}
bool dfs(){
int beta = -INF;
for (int i = ; i <= ; i++)
for (int j = ; j <= ; j++){
if (str[i][j] != '.') continue;
str[i][j] = 'x'; tot++;
int tmp = MinSearch(i, j, beta);
str[i][j] = '.'; tot--;
beta = max(beta, tmp);
if (beta == INF){
X = i;Y = j;
return ;
}
}
return ;
} int main () { char ch[];
while (scanf("%s", ch)!= EOF && ch[] != '$'){
init();
if (dfs()) printf("(%d,%d)\n", X - , Y - );//代表终点坐标
else printf("#####\n");
}
return ;
}
【POJ1568】【极大极小搜索+alpha-beta剪枝】Find the Winning Move的更多相关文章
- 算法笔记--极大极小搜索及alpha-beta剪枝
参考1:https://www.zhihu.com/question/27221568 参考2:https://blog.csdn.net/hzk_cpp/article/details/792757 ...
- 新手立体四子棋AI教程(3)——极值搜索与Alpha-Beta剪枝
上一篇我们讲了评估函数,这一篇我们来讲讲立体四子棋的搜索函数. 一.极值搜索 极值搜索是game playing领域里非常经典的算法,它使用深度优先搜索(因为限制最大层数,所以也可以称为迭代加深搜索) ...
- poj1568 Find the Winning Move[极大极小搜索+alpha-beta剪枝]
Find the Winning Move Time Limit: 3000MS Memory Limit: 32768K Total Submissions: 1286 Accepted: ...
- POJ 1568 极大极小搜索 + alpha-beta剪枝
极小极大搜索 的个人理解(alpha-beta剪枝) 主要算法依据就是根据极大极小搜索实现的. 苦逼的是,查了两个晚上的错,原来最终是判断函数写错了..瞬间吐血! ps. 据说加一句 if sum & ...
- 极大极小搜索思想+(α/β)减枝 【转自-----https://blog.csdn.net/hzk_cpp/article/details/79275772】
极大极小搜索,即minimax搜索算法,专门用来做博弈论的问题的暴力. 多被称为对抗搜索算法. 这个搜索算法的基本思想就是分两层,一层是先手,记为a,还有一层是后手,记为b. 这个搜索是认为这a与b的 ...
- 博弈论经典算法(一)——对抗搜索与Alpha-Beta剪枝
前言 在一些复杂的博弈论题目中,每一轮操作都可能有许多决策,于是就会形成一棵庞大的博弈树. 而有一些博弈论题没有什么规律,针对这样的问题,我们就需要用一些十分玄学的算法. 例如对抗搜索. 对抗搜索简介 ...
- 【迭代博弈+搜索+剪枝】poj-1568--Find the Winning Move
poj 1568:Find the Winning Move [迭代博弈+搜索+剪枝] 题面省略... Input The input contains one or more test cas ...
- poj 1568 Find the Winning Move 极大极小搜索
思路:用极大极小搜索解决这样的问题很方便!! 代码如下: #include <cstdio> #include <algorithm> #define inf 10000000 ...
- 软件发布版本区别介绍-Alpha,Beta,RC,Release
Alpha: Alpha是内部测试版,一般不向外部发布,会有很多Bug.除非你也是测试人员,否则不建议使用. 是希腊字母的第一位,表示最初级的版本 alpha就是α,beta就是β alpha版就是比 ...
- 软工+C(2017第4期) Alpha/Beta换人
// 上一篇:超链接 // 下一篇:工具和结构化 注:在一次软件工程讨论课程进度设计的过程中,出现了这个关于 Alpha/Beta换人机制的讨论,这个机制在不同学校有不同的实施,本篇积累各方观点,持续 ...
随机推荐
- TCP Socket的通讯框架
http://www.oschina.net/p/simple-socketshttp://www.oschina.net/p/cwsshttp://www.oschina.net/p/tcpprox ...
- Shadow Register 是什么?
ARM处理器有个Shadow Register的概念,查了很多资料,语焉不详,究竟是什么意思呢? 这其实是个和硬件有关的概念. 有些register是2层的,第一层是供CPU访问,第二层供Hw访问. ...
- Domino - SGU 101 (欧拉路径)
题目大意:这是一个多米诺骨游戏,这个游戏的规则就是一个连着一个,现在给出 N 个多米诺,每个多米诺两边都有一个编号,相邻的多米诺的编号要一致,当然多米诺是可以翻转的(翻转就加‘-’,不翻转是‘+’), ...
- bzoj4448 SCOI2015 情报传递 message
传送门bzoj4448 题解 离线之后构建树上主席树,每个点的线段树维护到根路径的信息,不用链剖(我的链剖只是拿来求\(\mathrm{lca}\)的),时空复杂度\(O(n\log{n})\). c ...
- 使用Morphia框架操作mongodb
1. mac 下 安装mongodb sudo brew update sudo brew install mongodb sudo brew services mongodb start 2. ...
- StrutsPrepareAndExecuteFilter(转)
http://www.iteye.com/topic/829843 一.概述 Struts2的核心是一个Filter,Action可以脱离web容器,那么是什么让http请求和action关联在一起 ...
- Java Web中资源的访问路径
在web应用中,以“/”开头的是绝对路径,不以“/”开头的是相对路径. 在服务器端,通常都使用绝对路径.例如web.xml.struts.xml.servlet等的访问路径都是以“/”开始. 服务 ...
- AE二次开发中,过滤后的图层,实现缩放至图层效果
//featureClass是自己获取的featureClass,也可是sde中获取的. public void FilterAndZoomToLayer(IFeatureClass featureC ...
- [RxJS] Transformation operator: repeat
Operator repeat() is somewhat similar to retry(), but is not for handling operators. In this lesson ...
- systemTAP 学习
http://blog.csdn.net/moonvs2010/article/category/1570309