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 ...
随机推荐
- python入门12 列表list
列表使用率较高,方法也多. 列表的定义 #coding:utf-8 #/usr/bin/python """ 2018-11-10 dinghanhua 列表 " ...
- mysqlbinlog用法总结
通过binlog日志统计dml语句,找出操作频繁的表 mysqlbinlog --no-defaults --base64-output=decode-rows -v -v mysql-bin.0 ...
- css relative
一.relative和absolute相煎关系 relative限制absolute 1.限制left/top/right/bottom定位 如果父元素有relative,只能根据父元素进行定位 2. ...
- 记一次MySQL手工注入
本来想找个装安全狗的站试下绕过,safe dog没找到,但随便一搜搜到一个小站有SQLi,正好借此机会复习下手工注入(新版Firefox我吐槽一下,hackbar这么好用的工具,说阉割就阉割,哎) 小 ...
- 【luogu T24743 [愚人节题目5]永世隔绝的理想乡】 题解
题意翻译 我们来说说王的故事吧. 星之内海,瞭望之台.从乐园的角落告知汝等.汝等的故事充满了祝福.只有无罪之人可以进入——『永世隔绝的理想乡(Garden of Avalon)』! 题目背景 zcy入 ...
- 【luoguP1219】【USACO】八皇后
P1219 八皇后 题目描述 检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行.每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子. 上面的布局可以用序 ...
- code First 四
先从现有数据库获取代码: 我们创建模型的时候选择Code First就可以了 public ModelStudent() : base("name=ModelStudent") ...
- center os 文件读写权限
五.使用chmod和数字改变文件或目录的访问权限文件和目录的权限表示,是用rwx这三个字符来代表所有者.用户组和其他用户的权限.有时候,字符似乎过于麻烦,因此还有另外一种方法是以数字来表示权限,而且仅 ...
- Webpack4 学习笔记七 跨域服务代理
webpack 小插件使用 webpack 监听文件变化配置 webpack 处理跨域问题 Webpack 小插件使用 clean-webpack-plugin: 用于在生成之前删除生成文件夹的Web ...
- 洛谷P1731 [NOI1999]生日蛋糕(爆搜)
题目背景 7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层 生日蛋糕,每层都是一个圆柱体. 设从下往上数第i(1<=i<=M)层蛋糕是半径为Ri, 高度为Hi的圆柱 ...