Description
一个n*n(n>=2)棋盘上有黑白棋子各一枚。游戏者A和B轮流移动棋子,A先走。
A的移动规则:只能移动白棋子。可以往上下左右四个方向之一移动一格。
B的移动规则:只能移动黑棋子。可以往上下左右四个方向之一移动一格或者两格。
和通常的“吃子”规则一样,当某游戏者把自己的棋子移动到对方棋子所在的格子时,他就赢了。两个游戏者都很聪明,当可以获胜时会尽快获胜,只能输掉的时候会尽量拖延时间。你的任务是判断谁会赢,需要多少回合。
n<=20
Solution
若A不能一步吃掉B则必不赢,很显然是对抗搜索了
卡一卡连ab剪枝都不用。。。
Code
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
#define fill(x,t) memset(x,t,sizeof(x))
const int INF=1e9;
int dx[8]={-1,1,0,0,-2,2,0,0};
int dy[8]={0,0,-1,1,0,0,-2,2};
int n,rec[21][21][21][21][65][2];
bool check(int x,int y) {
return (x>=1&&y>=1&&x<=n&&y<=n);
}
int dfs(int x,int y,int a,int b,int s,bool w) {
if (s>=n*3) return INF;
if (x==a&&y==b) return (!w)?(INF):(0);
if (~rec[x][y][a][b][s][w]) return rec[x][y][a][b][s][w];
int ret=INF;
if (w) { ret=0; rep(k,0,3) {
int tx=x+dx[k],ty=y+dy[k];
if (check(tx,ty)) {
ret=std:: max(ret,dfs(tx,ty,a,b,s+1,!w));
}
} } else { rep(k,0,7) {
int tx=a+dx[k],ty=b+dy[k];
if (check(tx,ty)) {
ret=std:: min(ret,dfs(x,y,tx,ty,s+1,!w));
}
} }
rec[x][y][a][b][s][w]=ret+1;
return ret+1;
}
int main(void) { fill(rec,-1);
int r1,c1,r2,c2; scanf("%d%d%d%d%d",&n,&r1,&c1,&r2,&c2);
if (abs(r1-r2)+abs(c1-c2)==1) puts("WHITE 1");
else printf("BLACK %d\n", dfs(r1,c1,r2,c2,0,1));
return 0;
}