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. HDOJ/HDU 1321 Reverse Text(倒序输出~)

    Problem Description In most languages, text is written from left to right. However, there are other ...

  2. HDOJ/HDU 2551 竹青遍野(打表~)

    Problem Description "临流揽镜曳双魂 落红逐青裙 依稀往梦幻如真 泪湿千里云" 在MCA山上,除了住着众多武林豪侠之外,还生活着一个低调的世外高人,他本名逐青裙 ...

  3. Bzoj 1222: [HNOI2001]产品加工 动态规划

    1222: [HNOI2001]产品加工 Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 486  Solved: 298[Submit][Status ...

  4. Matlab编程-图形处理功能

    绘图功能最基本的命令行:plot(y). 二维图形: (1) >> y=rand(100,1); >> plot(y) y是随机的实向量,以生成y的索引为横坐标,y为纵坐标绘图 ...

  5. Java GC专家系列1:理解Java垃圾回收

    了解Java的垃圾回收(GC)原理能给我们带来什么好处?对于软件工程师来说,满足技术好奇心可算是一个,但重要的是理解GC能帮忙我们更好的编写Java应用程序. 上面是我个人的主观的看法,但我相信熟练掌 ...

  6. Google生活

    本博文的主要内容有 .Google生活的介绍 1.Google生活的介绍 Google生活搜索的官网: http://shenghuo.google.cn/shenghuo/ http://sheng ...

  7. 关于python的开发工具——Canopy

    在学习和使用scikit-learn过程中,官方文档中推荐了两个IDE(Canopy and Anaconda),我分别在win7和mac下安装后,发现Canopy是可以用的.Anaconda没搞明白 ...

  8. JVM分代垃圾回收策略的基础概念

    由于不同对象的生命周期不一样,因此在JVM的垃圾回收策略中有分代这一策略.本文介绍了分代策略的目标,如何分代,以及垃圾回收的触发因素. 文章总结了JVM垃圾回收策略为什么要分代,如何分代,以及垃圾回收 ...

  9. bzoj3673 bzoj3674可持久化并查集

    并查集都写不来了qwq 之前写的是错的 sz的初值都是0,这样怎么加就都是0了,水这道题还是可以,但是加强版就过不了了 #include<cstdio> #include<cstri ...

  10. ArrayList and LinkedList

    ArrayList and LinkedList List代表一种线性表的数据结构,ArrayList则是一种顺序存储的线性表.ArrayList底层采用数组来保存每个集合元素,LinkedList则 ...