Description:
有一给定迷宫,从起始点出发,可以朝上下左右四个方向运动,一次只能运动一米(一格)。
请问:从起始点出发,要运动多长的路程,才能以最短路径到达终点?
Input:
给定迷宫示意图(#代表墙,不能通行;而 . 代表路,可以通行),并且给定迷宫的起始点和终点。
Output:
从起始点到终点的最短路径长度。
Sample Input 1
10 10
#s######.#
......#..#.#.##.##.#
.#........
##.##.####
....#....#
.#######.#
....#.....
.####.###.
....#...e#
0 1
9 8
Sample Output 1
The shortest path is 22 meters.
Sample Input 2
3 3
#s#
...
##e
0 1
2 2
Sample Output 3
The shortest path is 3 meters.
思路:
1. bfs的思想,是借助队列来依次完成第一层,第二层,第三层...的搜索。由于我们这里要求的最短路径是起始点到终点,所以从起始点出发使用bfs搜索,搜索到的每个点都是起始点到这个点的最短路(因为每次都只能走一步,而bfs也只是遍历上下左右的四个点,所以没有比bfs更短的路径走法) 。
2. 这里,在迷宫中行走,只能朝向上,向下,向左,向右四个方向行走。所以,为了方便,我们将(0,1)(0,-1)(1,0)(-1,0)这四种走法用两个数组保存起来,遍历的时候只需要通过一层循环就能达到走四个方向的效果。
Code:
#include<iostream>
#include<queue>
using namespace std;
char field[1001][1001];
int dist[1001][1001];
const int INF = 100001;
int N, M;
int sx, sy;//迷宫开始的坐标
int ex, ey;//迷宫结束的坐标
int tx[4] = { 0,-1,1,0 };
int ty[4] = { 1,0,0,-1 };
int bfs() {
for (int i = 0;i < N;i++)
for (int j = 0;j < M;j++)
dist[i][j] = INF;
dist[sx][sy] = 0;
queue<pair<int, int>> Que;//辅助遍历的队列
pair<int, int> p(sx,sy);
Que.push(p);
while (!Que.empty()) {
pair<int, int> pp = Que.front();
Que.pop();
if (pp.first == ex && pp.second == ey)
break;
for (int i = 0;i < 4;i++) {
int nx = pp.first + tx[i];
int ny = pp.second + ty[i];
if (nx >= 0 && nx < N && ny >= 0 && ny < M && field[nx][ny] != '#') {
dist[nx][ny] = min(dist[pp.first][pp.second] + 1, dist[nx][ny]);
pair<int, int> temp(nx, ny);
Que.push(temp);
}
}
}
return dist[ex][ey];
}
void solution() {
cin >> N >> M;
for (int i = 0;i < N;i++)
for (int j = 0;j < M;j++) {
cin >> field[i][j];
}
cin >> sx >> sy;
cin >> ex >> ey;
int ans = bfs();
if (ans != INF)
cout << "The shortest path is " << ans << " meters.";
else
cout << "There is no path that satisfies your request!";
return;
}
int main() {
solution();
return 0;
}