給定乙個大小為n*m的迷宮,由通道('.')和牆壁('#')組成,其中通道s表示起點,通道g表示終點,每一步移動可以達到上下左右中不是牆壁的位置。試求出起點到終點的最小步數。(本題假定迷宮是有解的)(n,m<=100)
樣例輸入:
10 10
#s######.#
......#..#
.#.##.##.#
.#........
##.##.####
....#....#
########.#
....#.....
.####.###.
....#...g#
這道題目以及解法均來自《挑戰程式設計競賽(第2版)》第34頁-36頁;書中解法使用了真正的佇列,而我在這裡是用了陣列模擬佇列,但是結果都是一樣的。
個人覺得這個例題很好地表現了廣度優先搜尋是如何與佇列先進先出(fifo)的思想聯絡起來的,通過不斷取得某個狀態後能夠達到的所有狀態並將其加入佇列, 並且由於佇列本身的特性先加入佇列的狀態總是先得到處理,這樣就達到了乙個目的:總是先將需要轉移次數更少的狀態進行分析處理,換句話說就是總是取得了這個狀態的樹中更接近根部的節點,又或者是總是讓搜尋樹的廣度得到盡可能增加。
在這個問題中,找到從起點到終點的最短路徑其實就是乙個建立佇列的過程:
1.從起點開始,先將其加入佇列,設定距離為0;
2.從佇列首端取出位置,將從這個位置能夠到達的位置加入佇列,並且讓這些位置的距離為上乙個位置的距離加上1;
3.迴圈2直到將終點新增到佇列中,這說明我們已經找到了路徑;
注意到在這個過程中,每次處理的位置所對應的距離是嚴格遞增的,因此一旦找到終點,當時的距離就是最短距離;
同樣基於這個原因,搜尋可移動到的位置所使用的判斷條件中不僅僅是不碰牆壁、不超過邊界,還有乙個就是沒有到達過,因為如果已經到達了這個位置,這說明已經有更短的路徑到達這個位置,這次到達這個位置的路徑是更差的,不可能得到更好的最終解。
#include#includeusing namespace std;
const int inf = 100000000;
char map[3000][3000];
int d[3000][3000];
int mov[4][2] = ;
int n,m,sx,sy,gx,gy;
pair que[1010];
int bfs()
}que[til].first = sx;
que[til++].second = sy;
d[sx][sy] = 0;
while(frt != til)}}
return d[gx][gy];
}int main()
if(map[i][j] == 'g')}}
int res = bfs();
res != inf ? printf("%d",res) : printf("-1");
return 0;
}
迷宮問題bfs
迷宮問題 採用佇列的廣度優先遍歷 bfs 思想是從乙個頂點v0開始,輻射狀地優先遍歷其周圍較廣的區域 找到的解為最優解 include define m 8 define n 8 define maxsize 1000 typedef struct box typedef struct qutype...
迷宮問題BFS
the code 資料結構迷宮.cpp 定義控制台應用程式的入口點。include stdafx.h include include include include define n 4 定義迷宮為4 4 using namespace std struct pot 為記錄路徑的rec準備,座標 x...
迷宮問題bfs
小明置身於乙個迷宮,請你幫小明找出從起點到終點的最短路程。小明只能向上下左右四個方向移動。輸入包含多組測試資料。輸入的第一行是乙個整數t,表示有t組測試資料。每組輸入的第一行是兩個整數n和m 1 n,m 100 接下來n行,每行輸入m個字元,每個字元表示迷宮中的乙個小方格。字元的含義如下 s 起點 ...