题意:
一个n*n(n>=2)棋盘上有黑白棋子各一枚。游戏者A和B轮流移动棋子,A先走。
A的移动规则:只能移动白棋子。可以往上下左右四个方向之一移动一格。
B的移动规则:只能移动黑棋子。可以往上下左右四个方向之一移动一格或者两格。
和通常的“吃子”规则一样,当某游戏者把自己的棋子移动到对方棋子所在的格子时,他就赢了。两个游戏者都很聪明,当可以获胜时会尽快获胜,只能输掉的时候会尽量拖延时间。你的任务是判断谁会赢,需要多少回合。
比如n=2,白棋子在(1,1),黑棋子在(2,2),那么虽然A有两种走法,第二个回合B总能取胜。
题解:
n较小,直接搜。
但是成环,所以还要记个步数。
感受一下,最多不会走太多步,大概3n左右。
code:
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std;
const int inf=1<<28;
int f[21][21][21][21][61][2];
int yh[10]={-1,0,1,0,-2,0,2,0};
int yl[10]={0,1,0,-1,0,2,0,-2};
int n,x,y,X,Y;
int dfs(int x,int y,int X,int Y,int c,int op)
{
int &g=f[x][y][X][Y][c][op];
if(x==X&&y==Y) return op*inf;
if(c>3*n) return inf;
if(g) return g;
g=op*inf;
for(int i=0;i<(op?8:4);i++)
{
int tx=x+yh[i],ty=y+yl[i];
if(tx<1||tx>n||ty<1||ty>n) continue;
if(!op) g=max(g,dfs(X,Y,tx,ty,c+1,1));
else g=min(g,dfs(X,Y,tx,ty,c+1,0));
}
return ++g;
}
int main()
{
scanf("%d %d %d %d %d",&n,&x,&y,&X,&Y);
if(abs(x-X)+abs(y-Y)<=1) return puts("WHITE 1"),0;
printf("BLACK %d",dfs(x,y,X,Y,0,0));
}