迷宫的最短路径
迷宫的最短路径
给定一个大小为 N×M 的迷宫。迷宫由通道和墙壁组成,每一步可以向邻接的上下左右四格
的通道移动。请求出从起点到终点所需的最小步数。请注意,本题假定从起点一定可以移动
到终点。
N=10, M=10(迷宫如下图所示。'#','.','S','G'分别表示墙壁、通道、起点和终点)
#S######.#
......#..#
.#.##.##.#
.#........
##.##.####
....#....#
.#######.#
....#.....
.####.###.
....#...G#
22
宽度优先搜索按照距开始状态由近及远的顺序进行搜索,因此可以很容易的用来求最短路径,最少操作之类问题的答案. (可以构造成pair或者编码成int来表达状态)
当状态更加复杂时,就需要封装成一个类来表示状态了.
虽然到达终点时就会停止搜索,可如果继续下去直到队列为空的话,就可以计算出各个位置的最短距离.此外,如果搜索到最后,d依然为INF的话,便可得知这个位置就是无法从起点发到达的位置.
1 const int INF = 100000000; 2 3 typedef pair<int,int> p;//使用pair表示状态时,使用typedef会更加方便一些 4 5 char maze[MAX_N][MAX_M+1]; //表示迷宫的字符串的数组 6 int N,M; 7 int sx,sy; //起点坐标 8 int gx,gy; //终点坐标 9 10 int d[MAX_N][MAX_M+1]; //表示迷宫的字符串的数组 11 12 int dx[4]={1,0,-1,0}; //4个方向移动的向量 13 int dy[4]={0,1,0,-1}; 14 15 16 //求从(sx,sy)到(gx,gy)的最短距离 17 //如果无法到达,则是INF 18 int bfs() 19 { 20 queue<P> que; 21 //把所有的位置都初始化为INF 22 for(int i=0; i<N; i++){ 23 for(int j=0; j<M; j++){ 24 d[i][j]=INF;//将起点加入队列,并把这一地点的距离设置为0 25 } 26 } 27 que.push(P(sx,sy)); 28 d[sx][sy]=0; 29 30 //不断循环直到队列的长度为0 31 while(que.size()){ 32 //从队列的最前端取出元素 33 p=que.front(); 34 que.pop(); 35 //如果取出的状态已经是终点,则结束搜索 36 if(p.first==gx && p.second==gy) 37 break; 38 //四个方向 39 for(int i=0; i<4; i++){ 40 int nx=p.first+dx[i]; 41 int ny=p.second+dy[i]; 42 //判断是否可以移动以及是否已经访问过(d[nx][ny]!=INF即为已经访问过) 43 if(0<=nx && nx<N && 0<=ny && ny<M && maze[nx][ny]!='#' && d[nx][ny]==INF){ 44 //可以移动的话,则加入到队列,并且到位置的距离确定为到p的距离+1 45 que.push(P(nx,ny)); 46 d[nx][ny]=d[p.first][p.second]+1; 47 } 48 } 49 } 50 return d[gx][gy]; 51 } 52 53 void solve(){ 54 int ans=bfs(); 55 printf("%d\n",ans); 56 }
有些目标看似很遥远,但只要付出足够多的努力,这一切总有可能实现!