乙個迷宮可以用如下圖描述
0表示可以通過,1表示有障礙物。問題是在圖中是否可以找到一條路徑,從入口(左上頂點)到出口(右下頂點)。
主要思想是回溯法和深度優先搜尋
分析結合**看會更好
首先走一步,然後判斷是否到達出口,如果沒有到達出口,則找到要移動的相鄰的一步,(1)找到了,則保持好當前的位置(放入棧),然後移動到此找到的相鄰的位置繼續前進。那怎麼繼續前進?首先需要說明的是從乙個點前進有四個選擇,右,下,左,上這四個方向(可以分別用0,1,2,3表示)。那找到鄰近點後要怎麼前進?由於找到的是新的乙個點,所以也就有四個方向可以走,有人會說肯定有乙個方向行不通,因為當前位置就是從那個方向走來的,對,每當經過乙個點,都會對此點進行標記(設定為障礙)以防重複訪問,因此在遍歷四個方向時如果遇到來的那個方向肯定沒法過去,因為已經標記/設為障礙。(2)如果沒有找到鄰近的點呢,那麼就退回到前一步,如果無路可退,則說明沒法到達終點,返回結果。否則繼續前進。那此時該怎麼前進呢,肯定現在的這個方向不會再來了。那還需要像找到乙個鄰近點那樣從四個方向開始遍歷嗎,不要那樣做,有點太重複了,假如我們要退回到的點是next,當前點是here,肯定有這種關係next->here,退回去意思就是說退回到來的地方,也就是說當前位置here是從next來的,here是next的四個方向選擇之一,在來here之前肯定也遍歷了此位置之前的方向,我們知道遍歷順序是按照右,下,左,上來的,所以只要知道here是next的那個方向,接下要前進的那個方向不就確定了嗎,這樣就避免了重複。那具體該怎麼確定呢,下面這段程式說明了此種情形
if (next.first == here.first)
else
需要注意的點是為了在處理邊界位置方便,能和內部位置處理方法保持一致,因此在地圖外圍新建了四堵牆。
程式**如下:
#include#include#include#includeusing namespace std;
bool findpath(vector>& mapin)
stack> path;
//方向設定
vector> offset = ,,, };//分別代表右,下,左,上四個方向
//初始化迷宮外面的障礙牆,這是為了處理邊界位置時比較方便
int n = mapin.size();
vectorvtemp(n + 2, 1);
vector> map(n + 2, vtemp);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
pairhere(1, 1);
map[1][1] = 1; //表示已經從出口出來了
int option = 0, lastoption = 3;
while (here.first < n || here.second < n)
++option;
} if (option <= lastoption)
else
pairnext = path.top();
path.pop();
if (next.first == here.first)
else
here = next;
} }return true;
}int main()
, ,,,
,};cout << findpath(mapin) << endl;
system("pause");
return 0;
}
當然如果要找的是最短路徑,可以檢視此文 尋找迷宮路徑
尋找迷宮路徑其實就是遍歷每乙個可能的路徑,碰到能夠成功的路徑就返回。bool findpath position here here.row 1 here.col 1 maze 1 1 1 防止回到入口 int option 0 下一步 int lastoption 3 尋找一條路徑 while h...
尋找迷宮中的最短路徑
給定乙個n m的二維整數陣列,用來表示乙個迷宮,陣列中只包含0或1,其中0表示可以走的路,1表示不可通過的牆壁。最初,有乙個人位於左上角 1,1 處,已知該人每次可以向上 下 左 右任意乙個方向移動乙個位置。請問,該人從左上角移動至右下角 n,m 處,至少需要移動多少次。資料保證 1,1 處和 n,...
自動尋找走出迷宮的最短路徑
演算法心得 1.利用廣度優先遍歷 bfs 實現尋找最短路徑 2.利用樹的思想,將每走一步的終點與它的起點相連線,這樣就能在最後把整條最短路徑找出來 設定乙個結構體,儲存座標 struct note que size size 儲存座標和連線指標 struct tree ans size 2 size...