bzoj3106 [cqoi2013]棋盤遊戲
阿新 • • 發佈:2017-12-31
方向 轉移 raw endif log define href == http
輸入僅一行,包含五個整數n, r1, c1, r2, c2,即棋盤大小和棋子位置。白色棋子在(r1,c1),黑色棋子在(r2,c2)(1<=r1,c1,r2,c2<=n)。黑白棋子的位置保證不相同。
Description
一個n*n(n>=2)棋盤上有黑白棋子各一枚。遊戲者A和B輪流移動棋子,A先走。 l A的移動規則:只能移動白棋子。可以往上下左右四個方向之一移動一格。 l B的移動規則:只能移動黑棋子。可以往上下左右四個方向之一移動一格或者兩格。 和通常的“吃子”規則一樣,當某遊戲者把自己的棋子移動到對方棋子所在的格子時,他就贏了。兩個遊戲者都很聰明,當可以獲勝時會盡快獲勝,只能輸掉的時候會盡量拖延時間。你的任務是判斷誰會贏,需要多少回合。 比如n=2,白棋子在(1,1),黑棋子在(2,2),那麽雖然A有兩種走法,第二個回合B總能取勝。Input
Output
輸出僅一行,即遊戲結果。如果A獲勝,輸出WHITE x;如果B獲勝,輸出BLACK x;如果二者都沒有必勝策略,輸出DRAW。Sample Input
2 1 1 2 2Sample Output
BLACK 2HINT
n<=20
正解:對抗搜索。
首先如果先手不能在第一步就贏,那麽他就必輸,因為後手可以把先手圍在角落裏。
然後設$f[0/1][y][a][b][c][d]$表示當前是先手/後手,總共走了幾步,先手在$(a,b)$,後手在$(c,d)$,直接按照對抗搜索的方法轉移就行。
以前沒有寫過對抗搜索,還是掛一個鏈接:博弈基礎——極大極小搜索
1 #include <bits/stdc++.h> 2 #define il inline 3 #define RG register 4 #define ll long long 5 #define inf (1<<30) 6 7 using namespace std; 8 9const int d1[8]={1,0,-1,0,2,0,-2,0}; 10 const int d2[8]={0,1,0,-1,0,2,0,-2}; 11 12 int f[2][65][21][21][21][21],n,a,b,c,d; 13 14 il int gi(){ 15 RG int x=0,q=1; RG char ch=getchar(); 16 while ((ch<‘0‘ || ch>‘9‘) && ch!=‘-‘) ch=getchar(); 17 if (ch==‘-‘) q=-1,ch=getchar(); 18 while (ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-48,ch=getchar(); 19 return q*x; 20 } 21 22 il int dfs(RG int x,RG int y,RG int a,RG int b,RG int c,RG int d){ 23 if (y>3*n) return inf; if (a==c && b==d) return x?inf:0; 24 if (f[x][y][a][b][c][d]) return f[x][y][a][b][c][d]; RG int res; 25 if (x){ 26 res=inf; 27 for (RG int i=0,X,Y;i<8;++i){ 28 X=c+d1[i],Y=d+d2[i]; 29 if (X>=1 && X<=n && Y>=1 && Y<=n) 30 res=min(res,dfs(x^1,y+1,a,b,X,Y)); 31 } 32 } else{ 33 res=0; 34 for (RG int i=0,X,Y;i<4;++i){ 35 X=a+d1[i],Y=b+d2[i]; 36 if (X>=1 && X<=n && Y>=1 && Y<=n) 37 res=max(res,dfs(x^1,y+1,X,Y,c,d)); 38 } 39 } 40 return f[x][y][a][b][c][d]=res+1; 41 } 42 43 int main(){ 44 #ifndef ONLINE_JUDGE 45 freopen("chess.in","r",stdin); 46 freopen("chess.out","w",stdout); 47 #endif 48 n=gi(),a=gi(),b=gi(),c=gi(),d=gi(); 49 if (abs(a-c)+abs(b-d)==1) puts("WHITE 1"); 50 else printf("BLACK %d\n",dfs(0,0,a,b,c,d)); 51 return 0; 52 }
bzoj3106 [cqoi2013]棋盤遊戲