【详解】电子老鼠走迷宫问题

电子老鼠走迷宫问题

1.题目描述

如下图12*12方格图,找出一条自入口(2,9) 到出口(11,8)的最短路径,如下图。
黑色方块代表不可走,白色方块代表可走。

在这里插入图片描述

2.解题思路:

声明:上图从左上角开始为(0, 0)点,一个方块代表1个长度。在数据输入时:黑色方块用数字 1 表示,白色方块用数字 0 表示。

1.本题采用BFS(广度搜索的思想)进行考虑。

2.用队列q存储可以通过的结点,以绿色点(2,9)为起点(beginX,beginY)开始进行,把该点记为拓展结点,向拓展节点的上下左右四个方向进行搜索,如果拓展节点的下一结点可以通过,将该结点放入队列q,并定义了队列prevv作为记录该结点上一个位置信息,方便输出路径记录。

3.如果拓展结点下面没有可以继续通过的结点,将其出队,队头换为下一个未进行搜索的结点,只要队列不为空,循环重复上述步骤。直到第一次搜索到结束点(endX, endY)时,即为最短路径

4.在上下左右四个方向进行搜索时,采用坐标+1, -1的形式

在这里插入图片描述

5.对于路径记录并输出这块的处理如下,在搜索过程中,如果有符合条件的坐标在将其入队时一并将它的前一个位置信息存入prevv中。

当队列处理完成时,通过while()从最后一个位置开始向前找,并把对应的x,y坐标放入 ansX, ansY中,最后输出。

3.运行结果

在这里插入图片描述

4.代码

#include <iostream>
#include <cstring>
#include <vector>

using namespace std;

typedef pair<int, int> PII; //定义pair 对象

const int N = 110;
//定义g 二维数组为地图,0代表可走,1代表不可走;
//d数组代表每一个位置距离出发的路径长度,1个格子代表长度1
int g[N][N], d[N][N];   

int n, m;   //定义n, m 分别代表行列
int beginX, beginY; //定义起始点
int endX, endY;     //定义结束点

PII q[N * N], prevv[N][N];   //定义q,代表队列

vector<int> ansX, ansY; //定义容器记录路径坐标

int bfs()
{
    
    
    int hh = 0, tt = 0; //队头及游标
    //初始化队列
    q[0] = {
    
    beginX - 1, beginY - 1};
    //初始化d数组
    memset(d, -1, sizeof d);
    //初始化起始点为
    d[beginX - 1][beginY - 1] = 0;

    //定义 dx, dy ,分别代表上下左右四个方向
    int dx[4] = {
    
    -1, 0, 1, 0}, dy[4] = {
    
    0, 1, 0, -1};

    while(hh <= tt) //当队列不空时执行循环
    {
    
    
        auto t = q[hh ++];  //每次取队头

        for (int i = 0; i < 4; i ++)
        {
    
    
            int x = t.first + dx[i], y = t.second + dy[i];
            //判断是否当前点可走
            if (x >= 0 && x < n && y >= 0 && y < m && g[x][y] == 0 && d[x][y] == -1)
            {
    
       
                //如果当前点可走,d数组发生变化
                d[x][y] = d[t.first][t.second] + 1;
                prevv[x][y] = t;    //记录当前位置的上一个位置
                q[++ tt] = {
    
    x, y};  //x, y点入队
            }
        }
    }

    int x = endX - 1, y = endY - 1;
    while(x || y)
    {
    
       
        //将最短路径的x, y坐标从最后一个位置开始向前找,分别放入ansX, ansY中
        ansX.push_back(x);
        ansY.push_back(y);
        auto t = prevv[x][y];
        x = t.first, y = t.second;
    }

    return d[endX - 1][endY - 1];

}


int main()
{
    
    
    //初始化数据
    cin >> n >> m;
    cin >> beginX >> beginY >> endX >> endY;
    for (int i = 0; i < n; i ++)
        for (int j = 0; j < m; j ++)
            cin >> g[i][j];

    printf("从(%d,%d) 到 (%d, %d)的最短路径长度为:%d\n",beginX, beginY, endX, endY, bfs());
    cout << "最短路径为:" << endl;

    //遍历路径位置信息并输出
    for (int i = ansX.size() - 1; i >= 0; i --)
    {
    
    
        if (i)
            cout << "(" << ansX[i] + 1 << "," << ansY[i] + 1 << ")" << "->";
        else
            cout << "(" << ansX[i] + 1 << "," << ansY[i] + 1 << ")";
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/jiangcheng2016/article/details/110353740