1. 程式人生 > >bzoj3106 [cqoi2013]棋盤遊戲

bzoj3106 [cqoi2013]棋盤遊戲

方向 轉移 raw endif log define href == http

Description

一個n*n(n>=2)棋盤上有黑白棋子各一枚。遊戲者A和B輪流移動棋子,A先走。 l A的移動規則:只能移動白棋子。可以往上下左右四個方向之一移動一格。 l B的移動規則:只能移動黑棋子。可以往上下左右四個方向之一移動一格或者兩格。 和通常的“吃子”規則一樣,當某遊戲者把自己的棋子移動到對方棋子所在的格子時,他就贏了。兩個遊戲者都很聰明,當可以獲勝時會盡快獲勝,只能輸掉的時候會盡量拖延時間。你的任務是判斷誰會贏,需要多少回合。 比如n=2,白棋子在(1,1),黑棋子在(2,2),那麽雖然A有兩種走法,第二個回合B總能取勝。

Input

輸入僅一行,包含五個整數n, r1, c1, r2, c2,即棋盤大小和棋子位置。白色棋子在(r1,c1),黑色棋子在(r2,c2)(1<=r1,c1,r2,c2<=n)。黑白棋子的位置保證不相同。

Output

輸出僅一行,即遊戲結果。如果A獲勝,輸出WHITE x;如果B獲勝,輸出BLACK x;如果二者都沒有必勝策略,輸出DRAW。

Sample Input

2 1 1 2 2

Sample Output

BLACK 2

HINT

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 
 9
const 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]棋盤遊戲