题目详情

Description

给定一个大小为 N * M 的迷宫。迷宫由通道和墙壁组成,每一步可以向邻接的上下左右四格的通道移动。请求出从起点到终点所需的最小步数

限制条件:

N,M <= 100

Input

输入两个数字 N 和 M,分别表示迷宫的长和宽,用空格隔开

输入代表迷宫的字符串,N 行 M 列,由 '#','~','S','G' 组成,分别表示墙壁,通道,起点,终点

Output

从起点到终点所需的最小步数

Sample Input

10 10#S######.#......#..#.#.##.##.#.#........##.##.####....#....#.#######.#....#......####.###.....#...G#

Sample Output

22

题解

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;

;
+,MAX_M=+;
typedef pair<int,int> P; //把 pair看作结构体,typedef的用法,P就是该结构体的一个实例。该"结构体"内只有两个元素 

//输入
char a[MAX_N][MAX_M]; //表示迷宫的字符串数组
int N,M; //迷宫的长宽
int sx,sy; //起点坐标
int gx,gy; //终点坐标
int d[MAX_N][MAX_M]; //存放到各个位置的最短距离的数组

//向四个方向移动的向量:右、上、左、下
]={,,-,}; //dx[i]是向量的横坐标
]={,,,-}; //dy[i]是向量的纵坐标

//从(sx,sy)到(gx,gy)的最短距离。如果无法到达,则是INF
int bfs(){
    queue<P> que;

    ;i<N;++i){
        ;j<M;++j){
            d[i][j]=INF; //把所有位置的距离初始化为INF
        }
    }
    //将起点加入队列,并把这一地点的距离设置为0
    que.push(P(sx,sy));
    d[sx][sy]=;

    //不断循环直到队列为空
    while(que.size()){
        //从队列最前端取出元素
        P p=que.front();
        que.pop();
        //如果取出的状态已经是终点,结束搜索
        if(p.first==gx && p.second==gy){
            break;
        } 

        //四个方向的循环
        ;i<;++i){
            //移动后的位置记为 (nx,ny)
            int nx=p.first+dx[i],ny=p.second+dy[i];
            //判断是否可以移动,是否已经访问过该点(d[nx][ny]!=INF即为访问过)
            <=nx && nx<N && <=ny && ny<M && a[nx][ny]!='#' && d[nx][ny]==INF){
                //如果能够移动则加入队列,且到该位置的距离变成到 p 的距离 +1
                que.push(P(nx,ny));
                d[nx][ny]=d[p.first][p.second]+;
            }
        }
    }
    return d[gx][gy];
}

int main(){
    scanf("%d%d",&N,&M);
    ;i<N;++i){
        scanf("%s",a[i]);
    }
    ;i<N;++i){
        ;j<M;++j){
            if(a[i][j]=='S'){
                sx=i;
                sy=j;
            }
            if(a[i][j]=='G'){
                gx=i;
                gy=j;
            }
        }
    }
    int res=bfs();
    printf("%d",res);
    ;
}

本题中,状态是目前所在位置的坐标,可以构造成 pair 或者编码成 int 来表达状态。当状态更加复杂时,需要封装成一个类来表示

宽度优先搜索中,只要将已经访问过的状态用标记管理起来,就可以很好的做到由近及远的搜索。本题要求最短距离,可用 d[N][M] 数组保存。初始化时用充分大的常数 INF 初始化它,这样尚未到达的位置就是 INF,同时起到标记的作用

到达终点时就会停止搜索,如果继续搜索下去直到队列为空,可以计算出到各个位置的最短距离。如果搜索到最后,d 依然是 INF,这个位置就无法从起点到达


宽度优先搜索

宽度优先搜索可以用来求最短路径,最少操作之类的问题

对于同一个状态,宽度优先搜索只经过一次,因此时间复杂度:O(状态数 * 转移的方式)

宽度优先搜索与深度优先搜索类似,从某个状态出发,探索所有可以到达的状态。不同之处在于,宽度优先搜索总是先搜索距离初始状态近的状态

深度优先搜索利用栈进行计算,宽度优先搜索则利用了队列。搜索时首先将初始状态加到队列里,此后从队列的最前端不断取出状态,把从该状态可以转移到的状态中尚未访问过的部分加入队列,如此往复,直至队列为空或找到了问题的解

宽度优先搜索会把状态逐个加入队列,通常需要与状态数成正比的内存空间。反之,深度优先搜索与最大的递归深度成正比。一般与状态数相比,递归的深度不会太大,所以可以认为深度优先搜索更加节省内存

挑战程序设计——迷宫的最短路径(BFS)的更多相关文章

  1. 迷宫的最短路径 (BFS)

    N*M的迷宫,从起点到终点,求最短距离 宽度优先搜索按照距开始状态由近及远的顺序进行搜索,因此可以很容易的用来求最短路径,最少操作之类问题的答案.  (可以构造成pair或者编码成int来表达状态) ...

  2. BFS求解迷宫的最短路径问题

    题目:给定一个大小为N*M的迷宫,迷宫由通道('.')和墙壁('#')组成,其中通道S表示起点,通道G表示终点,每一步移动可以达到上下左右中不是墙壁的位置.试求出起点到终点的最小步数.(本题假定迷宫是 ...

  3. POJ 3984 迷宫问题(BFS)

    迷宫问题 Description 定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, ...

  4. 编程算法 - 迷宫的最短路径 代码(C++)

    迷宫的最短路径 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 给定一个大小为N*M的迷宫. 迷宫由通道和墙壁组成, 每一步能够向邻接的上下 ...

  5. 数据结构实习 Problem H 迷宫的最短路径

    数据结构实习 Problem H 迷宫的最短路径 题目描述 设计一个算法找一条从迷宫入口到出口的最短路径. 输入 迷宫的行和列m n 迷宫的布局 输出 最短路径 样例输入 6 8 0 1 1 1 0 ...

  6. Aizu 2249Road Construction 单源最短路变形《挑战程序设计竞赛》模板题

    King Mercer is the king of ACM kingdom. There are one capital and some cities in his kingdom. Amazin ...

  7. POJ.3894 迷宫问题 (BFS+记录路径)

    POJ.3894 迷宫问题 (BFS+记录路径) 题意分析 定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, ...

  8. 《挑战程序设计竞赛》2.3 动态规划-优化递推 POJ1742 3046 3181

    POJ1742 http://poj.org/problem?id=1742 题意 有n种面额的硬币,面额个数分别为Ai.Ci,求最多能搭配出几种不超过m的金额? 思路 据说这是传说中的男人8题呢,对 ...

  9. 挑战程序设计竞赛》P345 观看计划

                                                 <挑战程序设计竞赛>P345 观看计划 题意:一周一共有M个单位的时间.一共有N部动画在每周si时 ...

随机推荐

  1. 牛客网暑期ACM多校训练营(第二场) I Car 思维

    链接:https://www.nowcoder.com/acm/contest/140/I来源:牛客网 White Cloud has a square of n*n from (1,1) to (n ...

  2. GitHub 简单教程

    码农朋友们都知道,GitHub是一个面向开源及私有软件项目的托管平台,上面托管了众多的优秀的项目,比如Linux内核源码.Git源码.机器学习框架Tensorflow等等.当然,除了这些顶尖项目外,还 ...

  3. webstorm 突然不能用了?解决办法~

    首先   感谢http://idea.lanyus.com 提供的试用方法,就在刚刚,webstorm突然就不能使了,http://idea.lanyus.com立马给出了解决办法,就是在hosts文 ...

  4. 【LeetCode】162-寻找峰值

    题目描述 峰值元素是指其值大于左右相邻值的元素. 给定一个输入数组 nums,其中 nums[i] ≠ nums[i+1],找到峰值元素并返回其索引. 数组可能包含多个峰值,在这种情况下,返回任何一个 ...

  5. 项目案例模板之jdbc两种连接方式

    项目案例模板之jdbc两种连接方式 第一种连接方式 JDBCUtils.java package jdbc; ​ import org.junit.jupiter.api.Test; ​ import ...

  6. openresty域名动态解析

    工作中使用openresty,使用第三方服务API通过域名访问.但是,域名通过DNS解析出来之后,在openresty是有 配置解析阶段 很多时候我们会在 Nginx 配置文件里配置上一些域名,比如配 ...

  7. centos开启nginx服务成功,却无法访问。没有开启80端口。centos配置防火墙 开启80端口

    Linux配置防火墙 开启80端口 编辑配置文件/etc/sysconfig/iptables [root@weixinht ~]# vim /etc/sysconfig/iptables 1 # F ...

  8. tlc549

    #include <reg51.h> #include "TLC549.c" code uchar seven_seg[] = {0xc0, 0xf9, 0xa4, 0 ...

  9. 6.Sentinel源码分析—Sentinel是如何动态加载配置限流的?

    Sentinel源码解析系列: 1.Sentinel源码分析-FlowRuleManager加载规则做了什么? 2. Sentinel源码分析-Sentinel是如何进行流量统计的? 3. Senti ...

  10. 03 (OC)* UITableView优化

    一:cell注册和初始化 1:不注册cell 2:注册类 3:注册nib 4:storyboard 二:核心思想 1:UITableView的核心思想是:cell的重用机制.UITbleView只会创 ...