Files
python/TangDou/AcWing/MiniPath/188.cpp
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

68 lines
2.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
#define x first
#define y second
typedef pair<int, int> PII;
/*
不再是简单的4连通或8连通,而是按中国象棋的“日”的方式去走!
日:共8个方向
K:起点,H:终点,*:障碍, .:可以跳
就是一个BFS最短路径问题,关键在于如何跳“日”,其实本质还是dx8的参数配置问题了。
*/
const int N = 155, M = N * N;
int n, m;
char g[N][N];
PII q[M];
int dist[N][N]; // 距离数组
// 8个方向
int dx[] = {-2, -1, 1, 2, 2, 1, -1, -2};
int dy[] = {1, 2, 2, 1, -1, -2, -2, -1};
int ans = INF;
void bfs() {
// 初始化距离数组为-1
memset(dist, -1, sizeof dist);
// 出发点坐标
int sx, sy;
// 找出发点
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
if (g[i][j] == 'K') sx = i, sy = j;
// 队列
int hh = 0, tt = -1;
q[++tt] = {sx, sy};
dist[sx][sy] = 0; // 标识走过,防止走回头路
while (hh <= tt) {
PII t = q[hh++];
for (int i = 0; i < 8; i++) {
int x = t.x + dx[i], y = t.y + dy[i];
if (x < 0 || x >= n || y < 0 || y >= m) continue;
if (g[x][y] == '*') continue; // 障碍的位置用 * 来标记
if (~dist[x][y]) continue; // 已经走过不能再走,防止走回头路
if (g[x][y] == 'H') { // 草的位置用 H 来标记。
ans = dist[t.x][t.y] + 1; // 多跳一步吃到草
return; // 吃到草就OK了
}
dist[x][y] = dist[t.x][t.y] + 1; // 多跳一步
q[++tt] = {x, y}; // 入队列继续扩展
}
}
}
int main() {
cin >> m >> n; // 居然先输入列数,再输入行数,bt!
// 这个输入太讨厌了,居然只是按行读入,每次读取一行,那么cin读到的就是一个字符串,目标是一个字符数组的话,就直接进入字符数组了~,这与以前的题目不同,要注意
for (int i = 0; i < n; i++) cin >> g[i]; // 题意下标从0开始,注意~
// 找最短路
bfs();
// 输出
printf("%d\n", ans);
return 0;
}