给定一个n行m列的地图(每个格子不是空地就是障碍物),有一个人在地图上移动,他可以上下左右四个方向移动,但不能穿过障碍物。他的初始位置为(x0,y0),他想要到达目标位置(x1,y1),问他最少需要移动多少步。
算法流程如下:
- 定义一个结构体表示一个点的位置和步数。
- 将起点(x0,y0)入队。
- 当队列非空时,取出队列的首元素,判断是否为终点(x1,y1),如果是,返回对应的步数。
- 否则,遍历当前点的四个相邻点,并且这些点在地图上不能是障碍物或者越界。对于每一个相邻点,将其位置和步数入队。
- 重复步骤3~4,直到队列为空或者找到目标点。
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
const int N = 110;
char g[N][N];
int dist[N][N];
int n, m;
struct Point {
int x, y;
int step;
};
bool check(int x, int y) {
if (x < 0 || x >= n || y < 0 || y >= m || g[x][y] == '#') return false;
return true;
}
int bfs(int sx, int sy, int tx, int ty) {
memset(dist, -1, sizeof dist);
dist[sx][sy] = 0;
queue<Point> q;
q.push({sx, sy, 0});
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};
while (q.size()) {
auto t = q.front();
q.pop();
if (t.x == tx && t.y == ty) return t.step;
for (int i = 0; i < 4; i++) {
int x = t.x + dx[i];
int y = t.y + dy[i];
if (check(x, y) && dist[x][y] == -1) {
dist[x][y] = t.step + 1;
q.push({x, y, t.step + 1});
}
}
}
return -1;
}
int main() {
cin >> n >> m;
int sx, sy, tx, ty;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> g[i][j];
if (g[i][j] == 'S') sx = i, sy = j;
else if (g[i][j] == 'T') tx = i, ty = j;
}
}
cout << bfs(sx, sy, tx, ty) << endl;
return 0;
}