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

题面省略。。。

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)
#####

大致题意::

    给定一个四乘四的棋盘,面对一个残局;问先手再下一步是否可以达成最终的胜利;若可以则输出按顺序的坐标最小的那个。

解决思路:

    (我给起的名字是博弈搜索算法,其实是极大极小搜索算法!)

    博弈迭代思想+搜索+剪枝。
    思路解释起来很麻烦,简单说就是:枚举先手一步,针对新加的新手一步--然后判断是否后手无论怎么下就注定是死局......

注意:

   1、在迭代的过程中,平局也是后手胜,因为题目仅要求先手是否面对的是必赢局!
         2、我的博客专栏胡搞里也有相关的可以瞅瞅!http://www.cnblogs.com/zhazhaacmer/category/1137385.html

带注释的题解(第二种check()为超时的判断局面的函数):
 
 char mp[][];
int check(int x,int y,char mp[][]){ //判定新更改的点(x,y)是否会构成胜利的局面,两斜/横/竖
if(x==y&&mp[][]!='.'&&mp[][]==mp[][]&&mp[][]==mp[][]&&mp[][]==mp[][])
return (mp[][]=='x'?:);
if(x+y==&&mp[][]!='.'&&mp[][]==mp[][]&&mp[][]==mp[][]&&mp[][]==mp[][])
return (mp[][]=='x'?:);
if(mp[x][]!='.'&&mp[x][]==mp[x][]&&mp[x][]==mp[x][]&&mp[x][]==mp[x][])
return (mp[x][]=='x'?:);
if(mp[][y]!='.'&&mp[][y]==mp[][y]&&mp[][y]==mp[][y]&&mp[][y]==mp[][y])
return (mp[][y]=='x'?:);
}
/* !!下面这种判断是否可以达到结束的局面的方法,时间复杂度高,毕竟把整个图跑了两遍!
int check1(char mp[4][5]){ //三种返回值,0表示前者,1表示后者,-1表示平局
for(int i=0;i<=3;i++){
if(mp[i][0]!='.'&&mp[i][0]==mp[i][1]&&mp[i][1]==mp[i][2]&&mp[i][2]==mp[i][3])
return (mp[i][0]=='x'?0:1);
}
for(int i=0;i<=3;i++){
if(mp[0][i]!='.'&&mp[0][i]==mp[1][i]&&mp[1][i]==mp[2][i]&&mp[2][i]==mp[3][i])
return (mp[0][i]=='x'?0:1);
}
if(mp[0][0]!='.'&&mp[0][0]==mp[1][1]&&mp[1][1]==mp[2][2]&&mp[2][2]==mp[3][3])
return (mp[0][0]=='x'?0:1);
if(mp[0][3]!='.'&&mp[0][3]==mp[1][2]&&mp[1][2]==mp[2][1]&&mp[2][1]==mp[3][0])
return (mp[0][3]=='x'?0:1); for(int i=0;i<=3;i++){
for(int j=0;j<=3;j++){
if(mp[i][j]=='.')
return -1;
}
}
return 1;//假设整个棋盘全部布满,平局就也是后者赢!
}
*/
int check_whole(){ // //判断全局都是点'.',若是则一定是平局,此种特例不特判必定超时
for(int i=;i<=;i++){
for(int j=;j<=;j++)
if(mp[i][j]!='.')
return false;
}
return true;
}
int ansx,ansy;//记录第一次下的点的x和y坐标,也就是step=0的时候! bool dfs(int x,int y,int op,int step){//对于op来说,先手X: 0要求必赢,后手1要求不败即可!
char ch = (op==)?'x':'o'; int val=check(x,y,mp);
if(val==op)
return true;
else if(val==!op)
return false; for(int i=;i<=;i++){
for(int j=;j<=;j++){
if(mp[i][j]=='.'){
mp[i][j]=ch;
if(dfs(i,j,!op,step+)==false){
mp[i][j]='.';
// printf("****step=%d****%d,%d ch=%c\n",step,i,j,(op==0)?'x':'o');
if(step==){
ansx=i;ansy=j;
}
return true;
}
mp[i][j]='.';
}
}
} return false;
} int main(){
char ch[];
while(scanf("%s",ch),ch[]!='$'){
for(int i=;i<=;i++)
scanf("%s",mp[i]);
if(check_whole()==true)//特判一次!全图都为点时,不忽略的话注定超时!
printf("#####\n");
else if(dfs(,,,)==true)
printf("(%d,%d)\n",ansx,ansy);
else
printf("#####\n");
} return ;
}

(头文件都回家过五一喽了!QWQ)

 

最新文章

  1. PHP 代码片段记录
  2. JVM垃圾回收机制总结:调优方法
  3. bootstrap-datetimepicker.js学习
  4. 第 6 章 贴近servlet
  5. POJ 1852 Ants
  6. js系列(8)简介
  7. python和tk实现桌面番茄时间(1)
  8. google 开放I/O源码
  9. Android 消息机制 (Handler、Message、Looper)
  10. 例10-9 uva1636简单概率问题
  11. jsp中文乱码 Servlet中文乱码 utf-8
  12. Python中的r+和a+
  13. 构建Docker Compose服务堆栈
  14. springboot(八)自定义Filter、自定义Property
  15. thinkphp中AJAX返回ajaxReturn()方法分析
  16. 学习shell脚本之前的基础知识(一)(学习记录帖)
  17. 广度优先遍历-BFS、深度优先遍历-DFS
  18. Django(五)在模板中使用静态文件
  19. thrust
  20. NPOI datatable导出类

热门文章

  1. iOS-关于创建真机调试证书(发布证书,测试证书,推送调试证书)【转】
  2. js 判断字符串是否为JSON格式
  3. composer安装扩展包异常
  4. QT 源码分析--1
  5. LeetCode 104. 二叉树的最大深度(Maximum Depth of Binary Tree)
  6. 029 Android 轮播图广告Banner开源框架使用
  7. docker 实践五:端口映射和容器互联
  8. Ubuntu 利用 mtd-utils 制作ubifs.img
  9. Jmeter之分布式测试/压测
  10. hdu 6625 three array (01-trie)