BFS算法 走迷宫问题 C++代码详细解释

题目:

从起点走向终点至少需要多少步(黄色为墙,不可走,每个节点只能走一次)

第一行为 n * m的地图规格接下来是m行地图数据,最后一行的头俩位是起始位置,尾俩位是终点位置;

输入样例:

5 4
1 1 2 1
1 1 1 1
1 1 2 1
1 2 1 1
1 1 1 2
1 1 4 3

输出样例:

7

题解:

数据结构:队列

节点结构:

struct node {
    int x; //x轴
    int y; //y轴
    int step; //走到此节点的步数
};
queue<node> q; //队列

初始操作:

1.定义v二维数组用于存放节点是否被访问(0未被访问,1被访问),定义a二维数组用于存放地图(1为路可走,2为墙不走)

int v[100][100], a[100][100];

2.输入数据

int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++) //输入地图
     for (int j = 1; j <= m; j++)
          cin >> a[i][j];
int startX, startY, pX, pY;
cin >> startX >> startY >> pX >> pY; //起始位置 终点位置

3.将起点位置存入队首

node start; //起点节点
start.x = startX; //设置起点的X轴
start.y = startY; //设置起点的Y轴
start.step = 0; //初始化步数为0
q.push(start); //存入队列
v[startX][startY] = 1; //设置此位置已被访问

循环操作(模拟走迷宫):

1.取出队首的x轴,y轴,步数

int x = q.front().x;
int y = q.front().y;
int step = q.front().step;

2.判断当前队首的x轴与y轴是否等于终点的x轴与y轴

      1)等于:找到终点,打印步数,退出循环

      1)不等于:继续执行

if (x == pX && y == pY) { //找到终点
    cout << step << endl;
    break;
}

3.遍历当前节点的周边节点是否可访问

  周边节点的位置:

int dx[] = {0, 1, 0, -1}; //左右上下
int dy[] = {1, 0, -1, 0}; //左右上下

访问条件:1、该节点未被访问  2、该节点不能为墙或不存在

      1)可访问:将被访问的节点存入队列,并设置已被访问

      1)不可访问:继续执行

for (int i = 0; i <= 3; i++) {
    int tx = x + dx[i]; //周边节点的X轴
    int ty = y + dy[i]; //周边节点的y轴
    if (v[tx][ty] == 0 && a[tx][ty] == 1) { // 1、该节点未被访问  2、该节点不能为墙或不存在
        node newNode;
        newNode.x = tx;
        newNode.y = ty;
        newNode.step = step + 1;
        q.push(newNode);
        v[tx][ty] = 1; //已被访问
    }
}

4.将当前节点删除

最终代码:

#include <bits/stdc++.h>
using namespace std;
int v[100][100], a[100][100];
struct node {
    int x; //x轴
    int y; //y轴
    int step; //走到此节点的步数
};
queue<node> q;
int main() {
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) //输入地图
        for (int j = 1; j <= m; j++)
            cin >> a[i][j];
    int startX, startY, pX, pY;
    cin >> startX >> startY >> pX >> pY;

    node start; //起点节点
    start.x = startX; //设置起点的X轴
    start.y = startY; //设置起点的Y轴
    start.step = 0; //初始化步数为0
    q.push(start); //存入队列
    v[startX][startY] = 1; //设置此位置已被访问

    int dx[] = {0, 1, 0, -1}; //左右上下
    int dy[] = {1, 0, -1, 0}; //左右上下
    while (!q.empty()) {

        int x = q.front().x;
        int y = q.front().y;
        int step = q.front().step;
        if (x == pX && y == pY) { //找到终点
            cout << step << endl;
            break;
        }

        for (int i = 0; i <= 3; i++) {
            int tx = x + dx[i]; //周边节点的X轴
            int ty = y + dy[i]; //周边节点的y轴
            if (v[tx][ty] == 0 && a[tx][ty] == 1) { //1、该节点未被访问  2、该节点不能为墙或不存在
                node newNode;
                newNode.x = tx;
                newNode.y = ty;
                newNode.step = step + 1; 
                q.push(newNode);
                v[tx][ty] = 1; //已被访问
            }
        }

        q.pop();
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_45462923/article/details/114459337