下棋
Accepts: 345
Submissions: 2382
Time Limit: 6000/3000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
Problem Description
N∗M 的棋盘上有一个受伤的国王与一个要去救援国王的骑士,他们每个单位时间必须同时移动一次寻找对方。如下图所示,黑色的图例表示国王(右)或骑士(左)当前所在的位置,那么灰色的位置表示在一次移动中他们可能到达的位置。国王伤势严重,因此他必须在K个单位时间内得到骑士的救援,否则会挂掉。问国王是否可以在K个单位时间内获得救援,如果可以,最短需要花多少个单位时间。
Input
第一行包含一个整数 T,(1≤T≤50) 代表测试数据的组数,接下来 T 组测试数据。
每组测试数据第一行包含三个整数 N,M,K , 且 2≤N,M≤1000 , 1≤K≤200 。第二行两个整数 Xking,Yking ,对应国王所在方格的坐标。第三行两个整数 Xknight,Yknight ,对应骑士所在方格的坐标。其中 1≤Xking,Xknight≤N,1≤Yking,Yknight≤M ,保证骑士与国王一开始不在同一个方格内且他们都可以移动。:
Output
对于每组测试数据,输出两行:
第一行输出:"Case #i:"。 i 代表第 i 组测试数据。
第二行输出测试数据的结果,如果国王可以得到救援,则输出最快需要花多少个单位时间。否则,输出“OH,NO!”。
Sample Input
2 3 2 1 1 1 3 1 3 3 1 1 1 1 2
Sample Output
Case #1: 1 Case #2: OH,NO!
广搜,先记录骑士每步到达的地方,看国王走相同的步数能否到达。
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <algorithm>
#define cle(a, i) memset(a, i, sizeof(a))
#define uf(i, a, b) for(int i = a; i <= b; i++)
using namespace std;
struct node
{
node(int X, int Y, int C) {
x = X;
y = Y;
cnt = C;
}
int x, y, cnt;
} ;
const int maxn = 1000 + 10;
int N, M, K, wx, wy, qx, qy;
int Qv[maxn][maxn], Wv[maxn][maxn], Ev[maxn][maxn];
const int Qd[8][2] = { 2, 1, 1, 2, 2, -1, 1, -2, -1, -2, -2, -1, -1, 2, -2, 1 };
const int Wd[8][2] = { 1, 1, 1, -1, 1, 0, -1, -1, -1, 1, -1, 0, 0, 1, 0, -1 };
queue<node> Q, W;
int Qcheck(int x, int y)
{
return x >= 1 && x <= N && y >= 1 && y <= M && !Qv[x][y];
}
int Wcheck(int x, int y)
{
return x >= 1 && x <= N && y >= 1 && y <= M && !Wv[x][y];
}
int bfs()
{
while(!Q.empty()) Q.pop();
while(!W.empty()) W.pop();
node next(node(0, 0, 0));
node now(node(0, 0, 0));
W.push(node(wx, wy, 0));
Q.push(node(qx, qy, 0));
for (int c = 0; c < K; c++) {
cle(Ev, 0); //每步骑士到达的地方
while (Q.front().cnt == c) { //将当前步数为c的都取出,拓展下一步
now = Q.front();
Q.pop();
uf(i, 0, 7) { //八个方向
int tx = now.x + Qd[i][0];
int ty = now.y + Qd[i][1];
if (Qcheck(tx, ty)) {
Qv[tx][ty] = 1;
Ev[tx][ty] = 1;
next.cnt = now.cnt + 1;
next.x = tx;
next.y = ty;
Q.push(next);
}
}
}
while (W.front().cnt == c) {
now = W.front();
W.pop();
uf(i, 0, 7) {
int tx = now.x + Wd[i][0];
int ty = now.y + Wd[i][1];
if (Wcheck(tx, ty)) {
if (Ev[tx][ty]) return c + 1; //若国王在相同的步数也到达,success
Wv[tx][ty] = 1;
next.cnt = now.cnt + 1;
next.x = tx;
next.y = ty;
W.push(next);
}
}
}
}
return -1;
}
int main()
{
int t, cas = 1;
scanf("%d", &t);
while (t--)
{
cle(Wv, 0);
cle(Qv, 0);
scanf("%d%d%d", &N, &M, &K);
scanf("%d%d%d%d", &wx, &wy, &qx, &qy);
int k = bfs();
printf("Case #%d:\n", cas++);
if (k == -1) printf("OH,NO!\n");
else printf("%d\n", k);
}
return 0;
}