大家都知道,至於迷宮的求解問題,可以用窮舉法進行求解。那麼什麼是窮舉法了,就是將每一種可能的情況都窮舉完。而具體到迷宮的求解問題上,由於在求解過程中可能會遇到某一路徑不可行的情況,此時我們就必須按原路返回,這時自然也就會想到棧的應用了,因爲棧的一個很重要的特性就是”先進後出”,可以用來記錄每次所探索的路徑,方便在原路返回的過程中,得到上一步所走路徑,再按此方法,退回到可以走得通的位置上,繼續探索下去,直到到達終點或者最終無法到達,正常退出程序爲止。
下面我們就一起來探索迷宮!!!
首先是得到迷宮地圖,這裏我們用文件流來實現。
void GetMaze(int *a, size_t n) { FILE* fout = fopen("MazeMap.txt", "r"); //打開迷宮地圖 assert(fout); for (size_t i = 0; i < n; i++) { for (size_t j = 0; j < n;) { char ch = fgetc(fout); //讀取一個字符 if (ch == '0' || ch == '1') { a[i*n + j] = ch - '0'; j++; } else { continue; } } } fclose(fout); }
給出迷宮地圖:
0爲通路,1爲牆
然後我們將迷宮打印出來
void PrintMaze(int* a, size_t n) { for (size_t i = 0; i < n; i++) { for (size_t j = 0; j < n; j++) { cout << a[i*n + j] << " "; } cout << endl; } cout << endl; }
接着定義位置結構體,用此結構體表示當前位置的橫縱座標
struct Pos { int _row; int _col; };
然後再從給定的入口位置開始對此位置的上下左右四個相鄰位置進行判斷,若爲1則行不通,若爲0,則可以走,,並將此位置進行壓棧。將走過的位置改爲2,以備在回退的時候可以用
bool MazePath(int* a, size_t n, Pos& entry, stack<Pos>& path) { Pos cur = entry; path.push(cur); //當前位置壓棧 while (!path.empty()) { a[cur._row *n + cur._col] = 2; //走過的位置標記爲2 Pos next = cur; //將當前位置進行標記 //上 next._row--; if (CheckIsAccess(a, n, next)) { cur = next; path.push(cur); continue; } //右 next = cur; next._col++; if (CheckIsAccess(a, n, next)) { cur = next; path.push(cur); continue; } //下 next = cur; next._row++; if (CheckIsAccess(a, n, next)) { cur = next; path.push(cur); continue; } //左 next = cur; next._col--; if (CheckIsAccess(a, n, next)) { cur = next; path.push(cur); continue; } //上下左右都走不通,回退 cur = path.top(); path.pop(); if (cur._row == n - 1) // 出口 { return true; } } return false; }
判斷當前位置的下一步是否走得通
bool CheckIsAccess(int* a, size_t n, Pos next) { assert(a); if ((next._col >= 0) && (next._col < n) && (next._row >= 0) && (next._row < n) && (a[next._row *n + next._col] == 0)) { return true; } else return false; }