迷宮的最短路徑
阿新 • • 發佈:2018-11-01
迷宮的最短路徑
給定一個大小為 N×M 的迷宮。迷宮由通道和牆壁組成,每一步可以向鄰接的上下左右四格
的通道移動。請求出從起點到終點所需的最小步數。請注意,本題假定從起點一定可以移動
到終點。
限制條件
N, M ≤ 100
輸入樣例:
N=10, M=10(迷宮如下圖所示。 '#', '.', 'S', 'G'分別表示牆壁、通道、起點和終點)
#S######.#
......#..#
.#.##.##.#
.#........
##.##.####
....#....#
.#.#####.#
..........
.####.###.
........G#
輸出:
16
解題思路: 用BFS廣度優先演算法遍歷。因為這裡只有四個方向可以動,所以就是遞迴的往這四個方向儘可能的移動,直到終點為止。
注: BFS演算法不像DFS一條路走到黑,BFS是擴散性的,走到一個點,就會向四周進行擴散,一直到所求的點為止,其中走過的點會被標記,所以每個點只會走一遍。這樣BFS的比DFS的好處就是,很方便的記錄從起始點到各個點的最短距離了。下面會有距離向量矩陣。
程式碼:
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
#define INF 2<<29
typedef struct _point
{
int x;
int y;
}POINT;
//寬度優先搜尋
int BFS(vector<vector<char> >& g, POINT& ptS, POINT& ptE)
{
int n = g.size(), m = g[0].size();
vector<vector<int> > dis(n);
//初始化距離向量
for (int i = 0;i < n;i++)
{
dis[i].resize(m);
for (int j = 0;j < m;j++)
dis[i][j] = INF;
}
POINT dt[4] = { {-1,0},{1,0},{0,-1},{0,1} }; //上下左右四個方向
queue<POINT> q;
//將起點入隊
q.push(ptS);
dis[ptS.x][ptS.y] = 0; //0表示已經走過了
//若佇列不為空或者沒有到達終點,則繼續遍歷
while (!q.empty())
{
//取出隊頭
POINT pCur = q.front();
q.pop();
//如果到達終點就結束
if(pCur.x == ptE.x&& pCur.y == ptE.y) break;
//嘗試往四個方向走
for (int i = 0; i < 4; i++)
{
POINT p = { pCur.x + dt[i].x,pCur.y + dt[i].y};
if (p.x >= 0 && p.x < n && p.y >= 0 && p.y < m && g[p.x][p.y] != '#' && dis[p.x][p.y] == INF)
{
//如果這個方向可以走,則將該點入隊
q.push(p);
//距離+1
dis[p.x][p.y] = dis[pCur.x][pCur.y] + 1;
}
}
}
return dis[ptE.x][ptE.y];
}
int main()
{
int n = 0,m= 0;
POINT ptS, ptE;
cin >> n >> m;
//輸入
vector<vector<char> > g(n);
for (int i = 0;i<n;i++)
{
g[i].resize(m);
for (int j = 0;j < m;j++)
{
cin >> g[i][j];
if (g[i][j] == 'S')
ptS = { i,j };
else if (g[i][j] == 'G')
ptE = { i,j };
}
}
//輸出
cout << BFS(g, ptS, ptE) << endl;
return 0;
}
距離向量:
# 0 # # # # # # 13 #
2 1 2 3 4 5 # 13 12 #
3 # 3 # # 6 # # 11 #
4 # 4 5 6 7 8 9 10 11
# # 5 # # 8 # # # #
8 7 6 7 # 9 10 11 12 #
9 # 7 # # # # # 13 #
10 9 8 9 10 11 12 13 14 15
11 # # # # 12 # # # 16
12 13 14 15 14 13 14 15 16 #
這就是迷宮的可行路線,每個點的距離都會被記錄下來。
最後求幫頂一下新部落格ACME。