题目描述:在一个n*m大小的网格中,1代表障碍物,0代表可以通过,从左上角走到右下角,每次只能上下左右移动一格,求最短路径长度。
示例输入:
5 5 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0
示例输出:
13
- #include
- #include
-
- using namespace std;
-
- const int N = 110;
-
- int n, m;
- int g[N][N]; // 存储地图(0表示可以通过,1表示障碍物)
- int dis[N][N]; // 存储每个位置到起点的最短路径长度,初始化为-1
- int dx[4] = {-1, 0, 1, 0}; // 四个方向的x坐标变化
- int dy[4] = {0, 1, 0, -1}; // 四个方向的y坐标变化
-
- struct Node { // 存储每个位置的坐标
- int x, y;
- };
-
- // 判断当前位置是否可以走(不越界且不是障碍物且之前没有被访问过)
- bool check(int x, int y) {
- if (x < 0 || x >= n || y < 0 || y >= m || g[x][y] == 1 || dis[x][y] != -1) {
- return false;
- }
- return true;
- }
-
- void bfs() {
- queue
q; - q.push({0, 0});
- dis[0][0] = 0; // 起点到起点的距离为0
-
- while (!q.empty()) {
- auto t = q.front();
- q.pop();
- for (int i = 0; i < 4; i++) {
- int x = t.x + dx[i];
- int y = t.y + dy[i];
- if (check(x, y)) { // 如果当前位置可以走,就进队
- q.push({x, y});
- dis[x][y] = dis[t.x][t.y] + 1; // 更新最短路径长度
- }
- }
- }
- }
-
- int main() {
- cin >> n >> m;
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < m; j++) {
- cin >> g[i][j];
- dis[i][j] = -1; // 初始化为-1
- }
- }
-
- bfs();
-
- cout << dis[n - 1][m - 1]; // 输出终点到起点的最短路径长度
-
- return 0;
- }
代码讲解:
- 定义
g数组存储地图,定义dis数组存储每个位置到起点的最短路径长度,初始化为-1。定义dx数组和dy数组存储四个方向的坐标变化。- 定义一个
check判断函数,判断当前位置是否可以走。若越界、为障碍物或已访问过,则返回假,否则返回真。- 首先将起点加入队列,并将起点到起点的距离为0。
- 当队列不空时,取出队首位置
t,并向四个方向探索。若当前位置可以走,则将当前位置加入队列,并更新最短路径长度。- 当队列为空时,结束搜索。
- 输出终点到起点的最短路径长度
dis[n-1][m-1]。