您的位置:首页 > 其它

[CQOI2013]棋盘游戏

2018-02-02 20:42 204 查看

Description

一个n*n(n>=2)棋盘上有黑白棋子各一枚。游戏者A和B轮流移动棋子,A先走。
A的移动规则:只能移动白棋子。可以往上下左右四个方向之一移动一格。
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

首先白子如果第一回合没吃掉黑子,那他就凉了

因为黑子总是能占据主动

因为可以黑棋走的距离比白棋大,黑棋可以下一步吃掉白棋,也可以下一步离开白棋的吃子范围

因为黑白子曼哈顿距离最大2×n

每一轮行动黑棋都可以接近至少1的距离(不会是0,因为没有意义),所以最多只有4×n轮

然后就是Y&*^*&%*

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int dx[8]={0,1,0,-1,0,2,0,-2};
int dy[8]={1,0,-1,0,2,0,-2,0};
int f[2][81][21][21][21][21],inf=2e9,n;
int dfs(int x,int y,int x1,int y1,int x2,int y2)
{int i;
int res;
if (y>3*n) return inf;
if (x1==x2&&y1==y2)
{
if (x==0) return 0;
else return inf;
}
if (f[x][y][x1][y1][x2][y2]) return f[x][y][x1][y1][x2][y2];
if (!x)
{
res=0;
for (i=0;i<4;i++)
{
int xx=x1+dx[i];
int yy=y1+dy[i];
if (xx>=1&&yy>=1&&xx<=n&&yy<=n)
{
res=max(res,dfs(x^1,y+1,xx,yy,x2,y2));
}
}
}
else
{
res=inf;
for (i=0;i<8;i++)
{
int xx=x2+dx[i];
int yy=y2+dy[i];
if (xx>=1&&yy>=1&&xx<=n&&yy<=n)
{
res=min(res,dfs(x^1,y+1,x1,y1,xx,yy));
}
}
}
f[x][y][x1][y1][x2][y2]=res+1;
return res+1;
}
int main()
{int v,x1,y1,x2,y2;
cin>>n>>x1>>y1>>x2>>y2;
if (abs(x1-x2)+abs(y1-y2)<=1) printf("WHITE 1\n");
else
{
v=dfs(0,0,x1,y1,x2,y2);
if (v>inf) printf("DRAW\n");
else printf("BLACK %d\n",v);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: