挑战程序设计——迷宫的最短路径(BFS)
题目详情
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)的更多相关文章
- 迷宫的最短路径 (BFS)
N*M的迷宫,从起点到终点,求最短距离 宽度优先搜索按照距开始状态由近及远的顺序进行搜索,因此可以很容易的用来求最短路径,最少操作之类问题的答案. (可以构造成pair或者编码成int来表达状态) ...
- BFS求解迷宫的最短路径问题
题目:给定一个大小为N*M的迷宫,迷宫由通道('.')和墙壁('#')组成,其中通道S表示起点,通道G表示终点,每一步移动可以达到上下左右中不是墙壁的位置.试求出起点到终点的最小步数.(本题假定迷宫是 ...
- 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, ...
- 编程算法 - 迷宫的最短路径 代码(C++)
迷宫的最短路径 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 给定一个大小为N*M的迷宫. 迷宫由通道和墙壁组成, 每一步能够向邻接的上下 ...
- 数据结构实习 Problem H 迷宫的最短路径
数据结构实习 Problem H 迷宫的最短路径 题目描述 设计一个算法找一条从迷宫入口到出口的最短路径. 输入 迷宫的行和列m n 迷宫的布局 输出 最短路径 样例输入 6 8 0 1 1 1 0 ...
- Aizu 2249Road Construction 单源最短路变形《挑战程序设计竞赛》模板题
King Mercer is the king of ACM kingdom. There are one capital and some cities in his kingdom. Amazin ...
- POJ.3894 迷宫问题 (BFS+记录路径)
POJ.3894 迷宫问题 (BFS+记录路径) 题意分析 定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, ...
- 《挑战程序设计竞赛》2.3 动态规划-优化递推 POJ1742 3046 3181
POJ1742 http://poj.org/problem?id=1742 题意 有n种面额的硬币,面额个数分别为Ai.Ci,求最多能搭配出几种不超过m的金额? 思路 据说这是传说中的男人8题呢,对 ...
- 挑战程序设计竞赛》P345 观看计划
<挑战程序设计竞赛>P345 观看计划 题意:一周一共有M个单位的时间.一共有N部动画在每周si时 ...
随机推荐
- P2746 [USACO5.3]校园网Network of Schools tarjan 缩点
题意 给出一个有向图,A任务:求最少需要从几个点送入信息,使得信息可以通过有向图走遍每一个点B任务:求最少需要加入几条边,使得有向图是一个强联通分量 思路 任务A,比较好想,可以通过tarjan缩点, ...
- HihoCoder - 1617 方格取数
HihoCoder - 1617 (从群主那里借鉴来的, 群主好强啊) 题意:中文题不解释... 题解: dp[X][i][j] 代表的是X是坐标之和 第一个人 走到位置 dp[i][x-i] 第二个 ...
- CF - 652 E Pursuit For Artifacts 边双联通
题目传送门 题解总结起来其实很简单. 把所有的边双联通分量缩成一个点,然后建立好新边, 然后再从起点搜到终点就好了. 代码: /* code by: zstu wxk time: 2019/02/23 ...
- hdu 5961 传递(暴力搜索)
我们称一个有向图G是传递的,当且仅当对任意三个不同的顶点a,,若G中有 一条边从a到b且有一条边从b到c ,则G中同样有一条边从a到c. 我们称图G是一个竞赛图,当且仅当它是一个有向图且它的基图是完全 ...
- 杭电2018暑假多校第一场 D Distinct Values hdu6301 贪心
Distinct Values Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- Spring.Net是怎么在MVC中实现注入的(原理)
本文将介绍Spring.Net(不仅仅是Spring.Net,其实所有的IoC容器要向控制器中进行注入,原理都是差不多的)在MVC控制器中依赖注入的实现原理,本文并没有关于在MVC使用Spring怎么 ...
- 【Offer】[25] 【合并两个排序的链表】
题目描述 思路分析 测试用例 Java代码 代码链接 题目描述 输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的.例如,输入图中的链表1和链表2,则合并之后的升序链表如链表3所 ...
- Day003_Linux基础——系统目录结构
Linux系统的目录结构: 圆型节点代指目录,方型节点代指文件. 图中省去了很多不常用的目录与文件. 稍后单独讲/proc目录与/var目录. /usr 目录. /usr/local 用户个人安装的软 ...
- 使用图灵机器人api搭建微信聊天机器人php实现
之前通过hook技术实现了微信pc端发送消息功能,如果在结合图灵机器人就能实现微信聊天机器人. 代码下载:http://blog.yshizi.cn/131.html 逻辑如下: 下面我简单介绍一下步 ...
- 005 Python开发环境配置
目录 一.概述 二.Python语言概述 2.1 Python语言的诞生 2.2 Monty Python组合 三.Python语言系统开发环境配置 四.Python程序编写与运行 4.1 Pytho ...