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 ...
随机推荐
- C语言 返回指针的函数
#include <stdio.h> char * test() { return "itcast"; } int main(int argc, const char ...
- swift 协议(结合扩展)的特点
协议的传统实现: 定义接口+实现协议 由抽象到具体: 协议的逆向实现(使用扩展): 由已存在的类型抽离部分功能作为协议,并让原体符合协议: 由具体到抽象: 向上抽离: 向上生成: 协议的缺省 ...
- POJ 3067 Japan 【树状数组经典】
题目链接:POJ 3067 Japan Japan Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 32076 Accep ...
- IntelliJ IDEA 快速搭建 Spring MVC环境
IntelliJ在业界被公认为最好的java开发工具之一,尤其在智能代码助手.代码自动提示.重构.J2EE支持.Ant.JUnit.CVS整合.代码审查. 创新的GUI设计等方面的功能可以说是超常的. ...
- 无法解析的外部符号 _WinMain@16,该符号在函数 ___tmainCRTStartup 中被引用
一,问题描述MSVCRTD.lib(crtexew.obj) : error LNK2019: 无法解析的外部符号 _WinMain@16,该符号在函数 ___tmainCRTStartup 中被引用 ...
- Hangfire 在asp.net core环境的使用
hf被定义为分布式后台服务,更加类似job作业的服务做作业的插件有quartz.net,JobScheduler 等当然,都有一些分别和适用的场景.1.安装需要安装Hangfire.CoreHangf ...
- 在idea配置jetty和创建(包、文件)javaWeb以及Servlet简单实现
在创建之前要安装好jetty jetty官网链接:https://jettylife.com/ 现在进行创建项目: 需要按照好jdk 现在进行添加jetty 现在进行配置 完成后ok ok 下面警告的 ...
- intellig idea中jsp或html数据没有自动保存和更换字体
主题一:保存数据jsp intellig idea是自动保存数据的,看到没有保存 解决方案: 成功解决 主题二:更换字体: 或者快捷键Ctel+Alt+s 成功解决
- SqlSugar之SqlQueryDynamic返回值处理
现在有个需求,有一张表每个月表名都会变的,但结构是一样的,我们不能再用类映射来完成的,我不能每个月都去手动添加,我们只能使用sql语句来完成这个需求.为了方便我这边选择的是SqlQueryDynami ...
- MarkDown/Html在线转换(支持代码高亮,可复制到微信公众号、今日头条)
MarkDown/Html在线转换能够将md渲染成html并且能保持代码高亮,可以方便的复制待格式的html粘贴到微信公众号,CSDN,简书,博客园,开源中国等. 扫码体验在线助手小程序 我是java ...