1568 Find the Winning Move 極小極大搜尋+alpha-beta剪枝
阿新 • • 發佈:2019-02-18
題目:在一個4*4的格子裡面,x和o兩個人玩遊戲,x畫'x',o畫'o',x先手,給定x和o都已經畫了一定步數的局面,問x是不是必勝的,如果是,輸出他應該畫在哪個位置
思路:極小極大搜尋+alpha-beta剪枝
程式碼:
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<iostream> #include<algorithm> #include<ctime> #include<cstdio> #include<cmath> #include<cstring> #include<string> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<list> #include<numeric> using namespace std; #define LL long long #define ULL unsigned long long #define INF 0x3f3f3f3f #define mm(a,b) memset(a,b,sizeof(a)) #define PP puts("*********************"); template<class T> T f_abs(T a){ return a > 0 ? a : -a; } template<class T> T gcd(T a, T b){ return b ? gcd(b, a%b) : a; } template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;} // 0x3f3f3f3f3f3f3f3f //0x3f3f3f3f char str[10][10]; int chess; int check(int r,int c){ int cnt=0; for(int i=0;i<4;i++)//同一行 if(str[r][i]=='x') cnt++; else if(str[r][i]=='o') cnt--; if(cnt==4||cnt==-4) return 1; cnt=0; for(int i=0;i<4;i++)//同一列 if(str[i][c]=='x') cnt++; else if(str[i][c]=='o') cnt--; if(cnt==4||cnt==-4) return 1; cnt=0; for(int i=0;i<4;i++)//正對角線 if(str[i][i]=='x') cnt++; else if(str[i][i]=='o') cnt--; if(cnt==4||cnt==-4) return 1; cnt=0; for(int i=0;i<4;i++)//反對角線 if(str[i][3-i]=='x') cnt++; else if(str[i][3-i]=='o') cnt--; if(cnt==4||cnt==-4) return 1; return 0; } int MaxSearch(int x,int y,int alpha); int MinSearch(int x,int y,int beta); int MinSearch(int x,int y,int beta){ int ans=1; if(check(x,y)) return ans;//x win if(chess==16) return 0;//x not win for(int i=0;i<4;i++) for(int j=0;j<4;j++){ if(str[i][j]!='.') continue; str[i][j]='o'; chess++; int tmp=MaxSearch(i,j,ans); str[i][j]='.'; chess--; if(ans>tmp) ans=tmp; if(ans<=beta) return ans; } return ans; } int MaxSearch(int x,int y,int alpha){ int ans=0; if(check(x,y)) return ans;//o win if(chess==16) return 0;//x not win for(int i=0;i<4;i++) for(int j=0;j<4;j++){ if(str[i][j]!='.') continue; str[i][j]='x'; chess++; int tmp=MinSearch(i,j,ans); str[i][j]='.'; chess--; if(ans<tmp) ans=tmp; if(ans>=alpha) return ans; } return ans; } int solve(int &x,int &y){ for(x=0;x<4;x++) for(y=0;y<4;y++){ if(str[x][y]!='.') continue; str[x][y]='x'; chess++; if(MinSearch(x,y,0)==1) return 1; str[x][y]='.'; chess++; } return 0; } int main(){ // freopen("D:\\input.txt","r",stdin); // freopen("D:\\output.txt","w",stdout); char ch[10]; while(~scanf("%s",ch)){ if(ch[0]=='$') break; for(int i=0;i<4;i++) scanf("%s",str[i]); chess=0; for(int i=0;i<4;i++) for(int j=0;j<4;j++) if(str[i][j]!='.') chess++; int x,y; if(solve(x,y)) printf("(%d,%d)\n",x,y); else printf("#####\n"); } return 0; }