POJ 3984ios
定義一個二維數組:編程
int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, };
它表示一個迷宮,其中的 1 表示牆壁,0 表示能夠走的路,只能橫着走或豎着走,不能斜着走,要求編程序找出從左上角到右下角的最短路線。數組
一個5 × 5
的二維數組,表示一個迷宮。數據保證有惟一解。優化
左上角到右下角的最短路徑,格式如樣例所示。spa
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0code
(0, 0)
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 4)
(4, 4)blog
這題是迷宮求最短路徑問題,因爲迷宮的邊權都爲 1, 因此優先使用寬度優先搜索 BFS
來作隊列
當BFS找到終點時,說明找到了一條最短路徑,因此要有一個記錄當前路徑的方法ip
*** 判斷遍歷到終點的方法 *** if ( tx == 4 && ty == 4 ) return tt - 1;
這裏的作法是開一個struct
數組來當隊列,裏面包含了當前遍歷到的點x, y
與當前點的父節點位置(由父節點擴展到點x,y)內存
找到終點時,咱們從終點開始看,找到它父節點在隊列中的位置,記錄它信息(x, y)
,再把這個父節點當成起始點,再次回溯它的父節點...
將父節點內存儲的座標逐一壓入堆棧中,當回溯的父節點位置爲-1
時,中止回溯,開始將堆棧中的內容所有彈出打印。
#include <iostream> #include <stack> #include <cstdio> using namespace std; const int N = 30; typedef pair<int, int> PII; /* 堆棧 stack 的元素爲 pair ,以 .first 和 .second 的方式訪問 pair 內的兩個元素 */ stack<PII> stck; struct stu { int x; int y; int p; /* p 即爲 當前點的父節點在隊列 q 中的下標 */ } q[N]; /* q 即爲 隊列, 使用數組來模擬隊列 */ /* 存放地圖數據 */ int a[10][10]; /* 表示 x, y 這個點是否進入過隊列,每一個點最多隻進入隊列一次(優化) */ bool st[N][N]; /* 下一個點的方向 */ int ne[2][4] = { {0, -1, 0, 1 }, {1, 0, -1, 0} }; /* bfs 返回終點在隊列中的位置 */ int bfs ( void ) { int hh = 0, tt = 0; // 隊頭hh 隊尾tt q[tt++] = { 0, 0, -1 }; // 添加隊頭元素,父節點設置爲-1,表示這是隊頭 st[0][0] = true; // (0, 0)點已添加進隊列 while ( tt > hh ) // 隊列不爲空則循環 { struct stu t = q[hh++]; // 取隊頭元素 /* 枚舉四個方向 */ for ( int i = 0; i < 4; i++ ) { int tx = t.x + ne[0][i]; int ty = t.y + ne[1][i]; /* 三大判斷條件 一、tx,ty在邊界內 二、當前點的值爲 0 三、當前點未被加入過隊列 */ if ( tx >= 0 && ty >= 0 && tx <= 4 && ty <= 4 && !st[tx][ty] && a[tx][ty] == 0 ) { st[tx][ty] = true; q[tt++] = {tx, ty, hh - 1}; // 當前隊首 - 1即爲它的父節點 } if ( tx == 4 && ty == 4 ) return tt - 1; } } } int main ( void ) { /* 將輸入數據存入地圖中 */ for ( int i = 0; i < 5; i++ ) for ( int j = 0; j < 5; j++ ) cin >> a[i][j]; int t = bfs(); // 接收BFS的返回值,此時 t 表明終點在隊列 q 中位置 /* i = t 只要 i != -1,意思就是沒有遍歷到頭節點 就一直循環, 每次循環後更新 i = q[i].p 意思是讓 i 變爲當前 i 所表示點的父節點的位置 每次循環將當前的座標壓入堆棧 */ for ( int i = t; i != -1; i = q[i].p ) stck.push ( {q[i].x, q[i].y} ); /* 只要堆棧不爲空,就彈出棧頂元素並輸出 */ while ( !stck.empty() ) { PII i = stck.top(); stck.pop(); printf ( "(%d, %d)\n", i.first, i.second ); } return 0; }
輸入 / 輸出:
若是有寫的很差的地方,或者有哪裏尚未理解的地方,請積極留言