• ybt 1252 广度优先搜索 走迷宫(二维、最小步数)


    1252:走迷宫


    时间限制: 1000 ms         内存限制: 65536 KB
    提交数: 7272     通过数: 3241

    【题目描述】

    一个迷宫由R行C列格子组成,有的格子里有障碍物,不能走;有的格子是空地,可以走。

    给定一个迷宫,求从左上角走到右下角最少需要走多少步(数据保证一定能走到)。只能在水平方向或垂直方向走,不能斜着走。

    【输入】

    第一行是两个整数,R和C,代表迷宫的长和宽。( 1≤ R,C ≤ 40)

    接下来是R行,每行C个字符,代表整个迷宫。

    空地格子用‘.’表示,有障碍物的格子用‘#’表示。

    迷宫左上角和右下角都是‘.’。

    【输出】

    输出从左上角走到右下角至少要经过多少步(即至少要经过多少个空地格子)。计算步数要包括起点和终点。

    【输入样例】

    5 5
    ..###
    #....
    #.#.#
    #.#.#
    #.#..

    【输出样例】

    9

    源代码
    #include<iostream>
    #include<cstdio>
    #include<math.h>
    #include<queue>
    #include<cstring>
    using namespace std;
    struct STU
    {
        int xx;
        int yy;
    };//定义结构体,分别表示点的横坐标和纵坐标
    
    queue<STU> q;//定义在STU结构下的结构题
    int go[5][2]={{0,0},{1,0},{-1,0},{0,1},{0,-1}};//向四个方向走
    int mapp[50][50],step[50][50];//mapp表示点的遍历情况,即vis;step表示走到该点的最小步数
    int n,m,qx,qy,tx,ty;
    char p[50][50];
    
    int bfs(int x,int y)
    {
         q.push((STU){x,y});//将第一组数据(起点)写入队列
         
         mapp[x][y]=1;
         step[x][y]=1;
         
         while(q.size()!=0)//当队列中的数据排空,即可停止
         {
             qx=q.front().xx;
             qy=q.front().yy;//取出队列中的第一个数
             q.pop();//没用了,扔掉
             
             if(qx==n&&qy==m)
             {
                 return step[qx][qy];//搜到终点,返回答案
             }
             
             for(int i=1;i<=4;i++)
             {
                 tx=qx+go[i][0];
                 ty=qy+go[i][1];//临近的下一个点
                 
                 if(tx<1||n<tx||ty<1||m<ty)
                 {
                     continue;//超出界限,跳过
                }
                
                if(mapp[tx][ty]==1||step[tx][ty]!=0)
                {
                    continue;//若该点已经走过,明显地不可能会是最小,跳过
                }
                
                mapp[tx][ty]=1;//将符合条件的下一个点标记为已读
                step[tx][ty]=step[qx][qy]+1;//步数加一
                q.push((STU){tx,ty});//编入队列,从当前开始继续向下搜索
             }
         }
    }
    
    int main(void)
    {
        cin>>n>>m;
        
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                cin>>p[i][j];//输入
                
                if(p[i][j]=='#') mapp[i][j]=1;//当该点是障碍物的话,也是不能走的,与已读的点一样,标记
                else mapp[i][j]=0;
            }
        }
        cout<<bfs(1,1)<<endl;//从左上角开始搜索
        return 0;
    }

    本题可以说是一道模板题
    还是比较简单的,但是有几个点需要注意,都已经给出了注释。

    广度优先搜索的原理:搜到某一个节点后,继续向下搜索,将可以的点编入队列,若不符合就退出,可以以排为单位进行搜索,不断减小搜索范围。
  • 相关阅读:
    Array.of()和Array()区别
    less常用方法
    javascript时间戳转换成yyyy-MM-DD格式
    javascript中标准事件流addEventListener介绍
    javascript中模块化知识总结
    搜索栏简单小案例
    css3伸缩布局中justify-content详解
    css3动画简单案例
    正则表达式的语法
    Beautisoup库
  • 原文地址:https://www.cnblogs.com/jd1412/p/12569244.html
Copyright © 2020-2023  润新知