AcWing 【844】 走迷宫

原题链接

acwing优质题解

BFS介绍+例题+模板(博主写的真的很不错)

dfs+bfs总结(写的超级详细,看完绝不后悔!!!)---强推

核心思路

  • 队列的使用:BFS 是一种逐层扩展的算法,因此使用队列 queue 来维护当前需要处理的节点,按顺序处理。每次从队列中取出一个节点,并将它的四个方向上的相邻节点加入队列中。

  • 距离数组 dis 的使用dis 用于记录从起点 (1, 1) 到当前点的最短距离。每当从某个点移动到相邻的未访问过的点时,记录相邻点的距离为当前点的距离加 1。

  • 地图边界检查与访问控制:在移动时,确保新的坐标 xn, yn 在矩阵边界内,并且没有访问过该点。

  • 优化策略:一旦找到终点 (n, m),立即返回结果,避免进行不必要的搜索。

全局变量定义

const int N=110;
int n,m;
int tu[N][N]; // 用于表示地图,0 表示可通行,1 表示障碍
int dis[N][N]; // 用于记录到每个点的最短距离
typedef pair<int,int> PII; // 定义一个 pair,用于存储坐标 (x, y)
queue<PII> q; // BFS 使用的队列
  • tu[N][N]:保存地图,其中 0 表示可以通行,1 表示障碍物。
  • dis[N][N]:保存到每个点的最短路径长度。
  • queue<PII> q;:定义一个队列,用于 BFS 的核心操作——存储需要处理的节点。

BFS函数实现

int bfs()
{
    if(n==1&&m==1)
        return 0;
    memset(dis,-1,sizeof dis); // 初始化距离数组
    q.push({1,1}); // BFS 从 (1,1) 开始
    dis[1][1]=0; // 起点的距离为 0
    int dx[4]={0,0,-1,1}; // x 方向的四个移动方向
    int dy[4]={1,-1,0,0}; // y 方向的四个移动方向

    while(!q.empty()) // 当队列不为空时,继续搜索
    {
        auto p=q.front();
        q.pop(); // 弹出队首元素
        int x=p.first,y=p.second; // 获取当前坐标
        int xn,yn;
        for(int k=0;k<4;k++) // 遍历四个方向
        {
            xn=x+dx[k]; // 计算新位置的 x 坐标
            yn=y+dy[k]; // 计算新位置的 y 坐标
            if(xn<=n && xn>=1 && yn>=1 && yn<=m && tu[xn][yn]==0 && dis[xn][yn]==-1) 
            {
                dis[xn][yn] = dis[x][y] + 1; // 更新距离
                if(xn==n && yn==m) return dis[xn][yn]; // 如果到达终点,返回距离
                q.push({xn,yn}); // 将新位置加入队列
            }
        }
    }
}

  • memset(dis,-1,sizeof dis):将 dis 数组全部初始化为 -1,表示所有点都未被访问。
  • q.push({1,1}):将起点 (1,1) 加入 BFS 队列,并设置起点的距离为 0
  • dx[4]dy[4]:分别表示在 x 轴和 y 轴上移动的四个方向。
  • while (!q.empty()) 循环中,队列 q 中存储的是当前层待处理的所有点,通过 q.pop() 弹出队首元素,检查四个方向上的点:
    • 如果新点 (xn, yn) 在边界内(xn>=1 && xn<=n && yn>=1 && yn<=m)。
    • 该点是可以通行的(tu[xn][yn]==0),且没有被访问过(dis[xn][yn]==-1)。
    • 满足这些条件后,将其标记为已访问,距离为前一个点的距离加 1,并将其加入队列。
    • 如果 (xn, yn) 是终点 (n, m),则返回其距离。

 主函数

int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            cin>>tu[i][j]; // 读取地图
        }
    }
    cout<<bfs()<<endl; // 输出最短距离
    return 0;
}

完整代码

#include<bits/stdc++.h>
using namespace std;
const int N=110;
int n,m;
int tu[N][N];
int dis[N][N];
typedef pair<int,int> PII;
queue<PII> q;
int bfs()
{
    if(n==1&&m==1)
        return 0;
    memset(dis,-1,sizeof dis);
    q.push({1,1});
    dis[1][1]=0;
    int dx[4]={0,0,-1,1};
    int dy[4]={1,-1,0,0};
    while(!q.empty())
    {
        auto p=q.front();
        q.pop();
        int x=p.first,y=p.second;
        int xn,yn;
        for(int k=0;k<4;k++)
        {
            xn=x+dx[k];
            yn=y+dy[k];
            if(xn<=n&&xn>=1&&yn>=1&&yn<=m&&tu[xn][yn]==0&&dis[xn][yn]==-1)
            {
                dis[xn][yn]=dis[x][y]+1;
                if(xn==n&&yn==m) return dis[xn][yn];
                q.push({xn,yn});
            }
            
            
        }
        
    }
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            cin>>tu[i][j];
        }
    }
    cout<<bfs()<<endl;
    return 0;
    
}

猜你喜欢

转载自blog.csdn.net/qq_73704268/article/details/142709342