POJ 1568 Find the Winning Move
Find the Winning Move
题意:
4*4的棋盘,给出一个初始局面,问先手有没有必胜策略?
有的话输出第一步下在哪里,如果有多个,按(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1) ... 的顺序输出第一个。没有输出“#####”。
分析:
极大极小搜索 或者 对抗搜索,α+β剪枝。
极大极小搜索:每个人都会进行最聪明的决策,假设有1号玩家为我们希望的玩家(即判断他能否有必胜的走法),那么对于一号玩家进行决策时,让他去所有后继状态中最大的,即Max节点。而二号玩家也会进行最聪明的决策,他会去所有后继状态中最小的,即Min节点。于是我们搜索出所有的后继状态的估价值, 判断。
α+β剪枝:思想:搜索到一个节点时,如果他进行最优决策,已经比父节点档当前的答案不优了,这个节点父节点是不会选的,这个节点的其他子节点的也不用搜了。
代码:
α+β剪枝:16ms
#include<cstdio> char g[][];
int ansx,ansy; int judge() {
int za = ,zb = ; // 主对角线
int fa = ,fb = ; // 副对角线
for (int i=; i<=; ++i) {
if (g[i][i] == 'x') za++;
else if (g[i][i]=='o') zb++;
if (g[i][-i] == 'x') fa++;
else if (g[i][-i]=='o') fb++;
}
if (za== || fa==) return ;
if (zb== || fb==) return -; for (int i=; i<=; ++i) {
int ra = ,rb = ; // 行
int ca = ,cb = ; // 列
for (int j=; j<=; ++j) {
if (g[i][j] == 'x') ra++;
else if (g[i][j] == 'o') rb++;
if (g[j][i] == 'x') ca++;
else if (g[j][i] == 'o') cb++;
}
if (ra == || ca == ) return ;
if (rb == || cb == ) return -;
} return ;
}
int Minimax(int player,int alpha,int beta) {
int res= judge();
if (res) return res;
if (player) {
for (int i=; i<=; ++i)
for (int j=; j<=; ++j)
if (g[i][j] == '.') {
g[i][j] = 'x';
res = Minimax(player^,alpha,beta);
g[i][j] = '.';
if (res > alpha) alpha = res,ansx = i,ansy = j;
if (alpha >= beta) return alpha;
}
return alpha; //-
}
else {
for (int i=; i<=; ++i)
for (int j=; j<=; ++j)
if (g[i][j] == '.') {
g[i][j] = 'o';
res = Minimax(player^,alpha,beta);
g[i][j] = '.';
if (res < beta) beta = res;
if (alpha >= beta) return beta;
}
return beta; //-
}
} int main() {
char op[];
while (scanf("%s",op) && op[]!='$') {
int cnt = ;
for (int i=; i<=; ++i) {
scanf("%s",g[i]+);
for (int j=; j<=; ++j)
if (g[i][j] != '.') cnt++;
}
if (cnt <= ) {
puts("#####");continue;
}
int ans = Minimax(,-,);
if (ans > ) printf("(%d,%d)\n",ansx-,ansy-);
else puts("#####");
}
return ;
}
没有α+β剪枝:63ms
#include<cstdio>
#include<cstdlib>
#include<algorithm> char g[][];
int ansx,ansy,f; int judge() {
int za = ,zb = ; // 主对角线
int fa = ,fb = ; // 副对角线
for (int i=; i<=; ++i) {
if (g[i][i] == 'x') za++;
else if (g[i][i]=='o') zb++;
if (g[i][-i] == 'x') fa++;
else if (g[i][-i]=='o') fb++;
}
if (za== || fa==) return ;
if (zb== || fb==) return -; for (int i=; i<=; ++i) {
int ra = ,rb = ; // 行
int ca = ,cb = ; // 列
for (int j=; j<=; ++j) {
if (g[i][j] == 'x') ra++;
else if (g[i][j] == 'o') rb++;
if (g[j][i] == 'x') ca++;
else if (g[j][i] == 'o') cb++;
}
if (ra == || ca == ) return ;
if (rb == || cb == ) return -;
} return ;
}
int Minimax(int player,bool flag) {
int res= judge(),t;
if (res) return res;
if (player) {
for (int i=; i<=; ++i)
for (int j=; j<=; ++j)
if (g[i][j] == '.') {
g[i][j] = 'x';
t = Minimax(player^,);
if (t > res) {
res = t;
if (flag) {
printf("(%d,%d)\n",i-,j-);
f = ;
return ;
}
}
g[i][j] = '.';
}
return res;
}
else {
res = ;
for (int i=; i<=; ++i)
for (int j=; j<=; ++j)
if (g[i][j] == '.') {
g[i][j] = 'o';
res = std::min(res,Minimax(player^,));
g[i][j] = '.';
}
return res; //-
}
} int main() {
char op[];
while (scanf("%s",op) && op[]!='$') {
int cnt = ;
f = ;
for (int i=; i<=; ++i) {
scanf("%s",g[i]+);
for (int j=; j<=; ++j)
if (g[i][j] != '.') cnt++;
}
if (cnt <= ) {
puts("#####");continue;
}
Minimax(,);
if (!f) puts("#####");
}
return ;
}
POJ 1568 Find the Winning Move的更多相关文章
- POJ 1568 Find the Winning Move(极大极小搜索)
题目链接:http://poj.org/problem?id=1568 题意:给出一个4*4的棋盘,x和o两人轮流放.先放够连续四个的赢.给定一个局面,下一个轮到x放.问x是否有必胜策略?若有,输出能 ...
- poj 1568 Find the Winning Move 极大极小搜索
思路:用极大极小搜索解决这样的问题很方便!! 代码如下: #include <cstdio> #include <algorithm> #define inf 10000000 ...
- 【迭代博弈+搜索+剪枝】poj-1568--Find the Winning Move
poj 1568:Find the Winning Move [迭代博弈+搜索+剪枝] 题面省略... Input The input contains one or more test cas ...
- poj1568 Find the Winning Move[极大极小搜索+alpha-beta剪枝]
Find the Winning Move Time Limit: 3000MS Memory Limit: 32768K Total Submissions: 1286 Accepted: ...
- 【poj1568】 Find the Winning Move
http://poj.org/problem?id=1568 (题目链接) 题意 两人下4*4的井字棋,给出一个残局,问是否有先手必胜策略. Solution 极大极小搜索.. 这里有个强力优化,若已 ...
- 【POJ1568】【极大极小搜索+alpha-beta剪枝】Find the Winning Move
Description 4x4 tic-tac-toe is played on a board with four rows (numbered 0 to 3 from top to bottom) ...
- POJ 1568 极大极小搜索 + alpha-beta剪枝
极小极大搜索 的个人理解(alpha-beta剪枝) 主要算法依据就是根据极大极小搜索实现的. 苦逼的是,查了两个晚上的错,原来最终是判断函数写错了..瞬间吐血! ps. 据说加一句 if sum & ...
- poj练习题的方法
poj1010--邮票问题 DFSpoj1011--Sticks dfs + 剪枝poj1020--拼蛋糕poj1054--The Troublesome Frogpoj1062--昂贵的聘礼poj1 ...
- poj -2975 Nim
Nim Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4312 Accepted: 1998 Description ...
随机推荐
- 团队第四次SCrum
scrum 第四次冲刺 一.项目目的 为生活在长大的学生提供方快捷的生活服务,通过帖子发现自己志同道合的朋友,记录自己在长大点滴.本项目的意义在于锻炼团队的scrum能力,加强团队合作能 ...
- python:类的基本特征------继承、多态与封装
一.继承 1,什么是继承 继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类 python中类的继承分为:单继承和多继承 cl ...
- POJ 2342 树的最大独立集
题意:在树的最大独立集的基础上,加上权值.求最大. 分析: 采用刷表的方式写记忆化,考虑一个点选和不选,返回方式pair 型. 首先,无根树转有根树,dp(root). 注意的是:u不选,那么他的子节 ...
- 【[CTSC2018]混合果汁】
题目 \(CTSC\)也有这么水的题啊 首先看到美味值来自于最小的美味值,我们就可以先考虑把所有的果汁按照美味值排序 接下来可以考虑二分,二分出一个\(mid\)我们只使用美味值大于等于\(mid\) ...
- Java+maven+selenium3+testng 自动化测试环境IDEA
idea .java环境变量jdk maven安装及环境变量配置这里就不多说了,网上有很多教程 这里我们只检测一下java.maven环境是否安装成功 win+R,运行cmd命令行:mvn -v ...
- 使用strtus2框架的json插件来完成ajax操作
------------------------------------------------------------------------------jsp------------------- ...
- Blog 使用Jsoup解析出html中的img元素
Jsoup主页:http://jsoup.org/ 在Blog.java 加入 private List<String> imageList=new LinkedList<Strin ...
- win10 安装YII2
YII2下载地址:http://www.yiichina.com/download 高级版本和基本版本的区别是: 基础版只有一个只有一个web应用,高级版则生成前后台.建议使用高级版,方便 Yii2框 ...
- 【luogu P1494 [国家集训队]小Z的袜子】 题解
题目链接:https://www.luogu.org/problemnew/show/P1494 #include <cstdio> #include <algorithm> ...
- js读取跨域webapi传送回来的cookie 要点
1.webapi 返回cookie时,httpOnly=false 2.webapi 接收Origins 不能为* 3.js端 请求时,withCredentials必须: true //`wit ...