武士风度的牛
农民 John 有很多牛,他想交易其中一头被 Don 称为 The Knight 的牛。这头牛有一个独一无二的超能力,在农场里像 Knight 一样地跳(就是我们熟悉的象棋中马的走法)。虽然这头神奇的牛不能跳到树上和石头上,但是它可以在牧场上随意跳,我们把牧场用一个 x,y的坐标图来表示。这头神奇的牛像其它牛一样喜欢吃草,给你一张地图,上面标注了 The Knight 的开始位置,树、灌木、石头以及其它障碍的位置,除此之外还有一捆草。现在你的任务是,确定 The Knight 要想吃到草,至少需要跳多少次。The Knight 的位置用 K 来标记,障碍的位置用 * 来标记,草的位置用 H 来标记。
这里有一个地图的例子:
11 | . . . . . . . . . .
10 | . . . . * . . . . .
9 | . . . . . . . . . .
8 | . . . * . * . . . .
7 | . . . . . . . * . .
6 | . . * . . * . . . H
5 | * . . . . . . . . .
4 | . . . * . . . * . .
3 | . K . . . . . . . .
2 | . . . * . . . . . *
1 | . . * . . . . * . .
0 ----------------------
1
0 1 2 3 4 5 6 7 8 9 0
The Knight 可以按照下图中的 A,B,C,D…这条路径用 5 次跳到草的地方(有可能其它路线的长度也是 5):
11 | . . . . . . . . . .
10 | . . . . * . . . . .
9 | . . . . . . . . . .
8 | . . . * . * . . . .
7 | . . . . . . . * . .
6 | . . * . . * . . . F<
5 | * . B . . . . . . .
4 | . . . * C . . * E .
3 | .>A . . . . D . . .
2 | . . . * . . . . . *
1 | . . * . . . . * . .
0 ----------------------
1
0 1 2 3 4 5 6 7 8 9 0
注意: 数据保证一定有解。
输入格式
第 1 行: 两个数,表示农场的列数 C 和行数 R。
第 2..R+1行: 每行一个由 C个字符组成的字符串,共同描绘出牧场地图。
输出格式
一个整数,表示跳跃的最小次数。
数据范围
1≤R,C≤150
输入样例:
10 11
..........
....*.....
..........
...*.*....
.......*..
..*..*...H
*.........
...*...*..
.K........
...*.....*
..*....*..
输出样例:
5
Solutions
用于查找从棋盘上的骑士到给定目标单元格的最短路径。
代码读取棋盘 n 的尺寸和棋盘本身作为一组字符。 棋盘表示为字符 g 的二维数组,其中每个字符代表棋盘中的一个单元格是否被阻塞。 具体来说,如果 g[i][j] 为“*”,则单元格被阻塞,否则解除阻塞。
bfs 函数由 main 函数调用,它使用广度优先搜索 (BFS) 算法在棋盘上找到从给定起始单元格 (kx, ky) 到目标单元格 (hx, hy) 的最短路径。 具体来说,该函数初始化一个二维数组dist来记录棋盘上从起始格到每个格的距离,然后使用队列从起始格开始进行BFS。 对于在 BFS 期间访问的每个单元格,该函数会在 dist 中更新到该单元格的距离并检查该单元格是否为目标单元格。 如果找到目标单元格,该函数将返回到该单元格的距离。
在 main 函数中,代码初始化一个二维数组 dist 来跟踪最短路径,然后调用 bfs 函数来查找从起始单元格到目标单元格的最短路径。 然后该函数输出到目标单元格的距离。
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
const int N = 160;
int n, m;
char g[N][N];
int dist[N][N];
int dx[8] = {1, 2, 2, 1, -1, -2, -2, -1}, dy[8] = {2, 1, -1, -2, -2, -1, 1, 2};
int bfs(int kx, int ky, int hx, int hy) {
memset(dist, -1, sizeof dist);
dist[kx][ky] = 0;
queue<PII> q;
q.push(make_pair(kx, ky));
while (q.size()) {
PII t = q.front();
q.pop();
for (int i = 0; i < 8; i ++ ) {
int tx = t.first + dx[i], ty = t.second + dy[i];
if (tx < 0 || tx >= m || ty < 0 || ty >= n) continue;
if (g[tx][ty] == '*') continue;
if (dist[tx][ty] != -1) continue;
if (tx == hx && ty == hy) return dist[t.first][t.second] + 1;
q.push(make_pair(tx, ty));
dist[tx][ty] = dist[t.first][t.second] + 1;
}
}
return -1;
}
int main() {
cin.tie(nullptr);
cout.tie(nullptr);
ios::sync_with_stdio(false);
cin >> n >> m;
int sx, sy, fx, fy;
for (int i = 0; i < m; i ++ ) {
for (int j = 0; j < n; j ++ ) {
cin >> g[i][j];
if (g[i][j] == 'K') sx = i, sy = j;
else if (g[i][j] == 'H') fx = i, fy = j;
}
}
cout << bfs(sx, sy, fx, fy) << endl;
return 0;
}