POJ 1568 Find the Winning Move(极小极大搜索+alpha-beta剪枝)

来源:互联网 发布:Ubuntu进程的创建命令 编辑:程序博客网 时间:2024/06/10 01:23

转载请注明出处,谢谢http://blog.csdn.net/acm_cxlove/article/details/7854526       by---cxlove 

题目:给出一个4*4的格子,一盘棋已经进行了部分,接下来是先手下,如果出现了连续4个同样的,就算胜。问先手有没有必胜策略

http://poj.org/problem?id=1568 

还是极大极小搜索,和之前的差不多

枚举起点,然后开始搜索

这里有一个强效剪枝,如果当前只下了4个或者4个以内的棋子,则必定没有必胜策略,直接从2S+到0ms

参考http://blog.csdn.net/qiqijianglu/article/details/7990650

极大极小搜索策略一般都是使用在一些博弈类的游戏之中:

这样策略本质上使用的是深度搜索策略,所以一般可以使用递归的方法来实现。在搜索过程中,对本方有利的搜索点上应该取极大值,而对本方不利的搜索点上应该取极小值。

极小值和极大值都是相对而言的。

在搜索过程中需要合理的控制搜索深度,搜索的深度越深,效率越低,但是一般来说,走法越好。

极大极小搜索可以分开写,也可以放在一起写。

#include<iostream>  #include<cstdio>  #include<map>  #include<cstring>  #include<cmath>  #include<vector>  #include<queue>  #include<algorithm>  #include<set>  #define inf 1<<30#define N 50005  #define maxn 100005  #define Min(a,b) ((a)<(b)?(a):(b))  #define Max(a,b) ((a)>(b)?(a):(b))  #define pb(a) push_back(a)  #define mem(a,b) memset(a,b,sizeof(a))  #define eps 1e-9  #define zero(a) fabs(a)<eps  #define LL long long  #define ULL unsigned long long  #define lson (step<<1)  #define rson (step<<1|1)  #define MOD 1000000007  #define mp(a,b) make_pair(a,b)  using namespace std;  char str[5][5];int X,Y,chess;//判断一个局面是否结束bool check(int x,int y){int tot=0;//横向判断for(int i=0;i<4;i++)if(str[x][i]=='o') tot++;else if(str[x][i]=='x') tot--;if(tot==4||tot==-4) return true;tot=0;//纵向判断for(int i=0;i<4;i++)if(str[i][y]=='o') tot++;else if(str[i][y]=='x') tot--;if(tot==4||tot==-4) return true;tot=0;//正对角线判断for(int i=0;i<4;i++)if(str[i][i]=='o') tot++;else if(str[i][i]=='x') tot--;if(tot==4||tot==-4) return true;tot=0;//反对角线判断for(int i=0;i<4;i++)if(str[i][3-i]=='o') tot++;else if(str[i][3-i]=='x') tot--;if(tot==4||tot==-4) return true;return false;}int MinSearch(int x,int y,int beta);int MaxSearch(int x,int y,int alpha);int MaxSearch(int x,int y,int alpha){int ans=-inf;//已经结束if(check(x,y)) return ans;//平局if(chess==16) return 0;for(int i=0;i<4;i++)for(int j=0;j<4;j++)if(str[i][j]=='.'){str[i][j]='x';chess++;int tmp=MinSearch(i,j,ans);str[i][j]='.';chess--;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(chess==16) return 0;for(int i=0;i<4;i++)for(int j=0;j<4;j++)if(str[i][j]=='.'){str[i][j]='o';chess++;int tmp=MaxSearch(i,j,ans);str[i][j]='.';chess--;ans=min(ans,tmp);//自己需要找的最高估价,如果当前比之前最差的低,剪枝if(ans<=beta) return ans;}return ans;}bool slove(){int beta=-inf;for(int i=0;i<4;i++)for(int j=0;j<4;j++)//枚举,然后搜索if(str[i][j]=='.'){str[i][j]='x';chess++;int tmp=MinSearch(i,j,beta);str[i][j]='.';chess--;beta=max(tmp,beta);if(beta==inf){X=i;Y=j;return true;}}return false;}int main(){char ch[5];while(scanf("%s",ch)!=EOF&&ch[0]!='$'){chess=0;for(int i=0;i<4;i++){scanf("%s",str[i]);for(int j=0;j<4;j++)chess+=str[i][j]!='.';}//这一步直接从2S+到0ms,哭~~~if(chess<=4){printf("#####\n");continue;}if(slove()) printf("(%d,%d)\n",X,Y);else printf("#####\n");}return 0;}


原创粉丝点击