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 <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的更多相关文章

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

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

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

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

  3. poj1568 Find the Winning Move[极大极小搜索+alpha-beta剪枝]

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

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

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

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

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

  6. 博弈论经典算法(一)——对抗搜索与Alpha-Beta剪枝

    前言 在一些复杂的博弈论题目中,每一轮操作都可能有许多决策,于是就会形成一棵庞大的博弈树. 而有一些博弈论题没有什么规律,针对这样的问题,我们就需要用一些十分玄学的算法. 例如对抗搜索. 对抗搜索简介 ...

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

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

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

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

  9. 软件发布版本区别介绍-Alpha,Beta,RC,Release

    Alpha: Alpha是内部测试版,一般不向外部发布,会有很多Bug.除非你也是测试人员,否则不建议使用. 是希腊字母的第一位,表示最初级的版本 alpha就是α,beta就是β alpha版就是比 ...

  10. 软工+C(2017第4期) Alpha/Beta换人

    // 上一篇:超链接 // 下一篇:工具和结构化 注:在一次软件工程讨论课程进度设计的过程中,出现了这个关于 Alpha/Beta换人机制的讨论,这个机制在不同学校有不同的实施,本篇积累各方观点,持续 ...

随机推荐

  1. poj -2975 Nim

      Nim Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4312   Accepted: 1998 Description ...

  2. Torque2D MIT 学习笔记(27) ---- ImageFont的使用以及字体ImageAsset的工具生成

    前言 ImageFont继承于SceneObject,是一个场景对象,支持例如旋转,缩放,移动加速度以及物理碰撞等一切Torque中场景对象的一切功能. ImageFont只支持ASCII编码表中的3 ...

  3. hdoj 3635 Dragon Balls【并查集求节点转移次数+节点数+某点根节点】

    Dragon Balls Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  4. HTTP 返回时间 概念 TTFB..

    课外学习部分: 什么是TTFB呢? 1.TTFB (Time To First Byte),是最初的网络请求被发起到从服务器接收到第一个字节这段时间,它包含了 TCP连接时间,发送HTTP请求时间和获 ...

  5. java James

    使用JavaMail发送电子邮件(案例) 需求: 使用JavaMail技术,实现从A账户给B账户发送一封电子邮件,标题为"会议通知",邮件内容为"XX你好!请于明天下午1 ...

  6. DevExpress LookUpEdit 下拉框基本操作

    <span style="font-size:14px;"> ArrayList list = new ArrayList(); //遍历皮肤,放到列表中 foreac ...

  7. HDU3336-Count the string(KMP)

    Count the string Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  8. 开始lisp的旅程

    不知道是不是<黑客与画家>的老pual太能忽悠了,一直想把他吹捧的lisp学习一下. 看common lisp和On lisp两本书也有一段时间了,中间还夹着看了一点SICP和land o ...

  9. docker-compose.yml 语法说明

    YAML 模板文件语法 默认的模板文件是 docker-compose.yml,其中定义的每个服务都必须通过 image 指令指定镜像或 build 指令(需要 Dockerfile)来自动构建. 其 ...

  10. Python基础 1----Python语言基础和Python环境准备与安装

    引导语: 人们学习Python是因为他们爱这门语言,因为他们追寻美,如果我雇用一个Python程序员,那么他们的技术将非常的棒 1 Python是一门跨平台的语言,是一种面向对象的动态编程语言 发布时 ...