題目:
給定一個 n x m大小的迷宮,其中 “*” 代表不可通過的牆壁,而 ’.‘代表平地,S表示起點,T表示終點。移動過程中,如果當前位置是(x,y)(下標從0開始),且每次只能往上下左右四個方向的平地移動,求從起點S到達終點T的最少步數。
.....
.*.*.
.*S*.
.***.
...T*
在上面的樣例中,S的坐標為(2,2),T的坐標為(4,3)。
輸入格式:
第一行給出m,n,表示迷宮的行,列;
下面每一行給出 n個字符,共 m行;
最后一行給出起點坐標S1,S2,終點坐標T1,T2。
輸出格式:
輸出從起點S到達終點T的最少步數, 不存在輸出 -1。
輸入樣例 1:
5 5
.....
.*.*.
.*S*.
.***.
...T*
2 2 4 3
輸出樣例 1:
11
輸入樣例 2:
5 5
.....
.*.*.
.*S*.
.***.
...T.
2 2 4 3
輸出樣例 2:
9
輸入樣例 3:
5 5
.....
.....
..S..
.....
...T.
2 2 4 3
輸出樣例 3:
3
直接上代碼。。。BFS總的來說,比寫的DFS代碼多一些,奈何時間復雜度好,並且有模板,不容易出現死循環!!!。
1 #include<iostream> 2 #include<queue> 3 #include<unordered_map> 4 using namespace std; 5 6 const int maxn = 100,INF = 0x3fffffff; 7 struct Node { 8 int x,y; 9 int layer = 0;//記錄從起點S到達該位置的最少步數(層數) 10 } node; 11 char maze[maxn][maxn]; 12 int m,n,MIN = INF; 13 int S1,S2,T1,T2; 14 int X[] = {0,0,1,-1};//控制訪問的四個方向,新技能 get !!! 15 int Y[] = {1,-1,0,0}; 16 bool inque[maxn][maxn] = {false};//標記元素是否已經入隊---這樣不會改變矩陣原本的狀態,新技能get !!! 17 bool judge(int i,int j) { 18 if(i < 0 || j < 0 || i>= m||j>= n || maze[i][j] == '*' || inque[i][j] == true) 19 return false; 20 return true; 21 } 22 void BFS(int i, int j) { 23 queue<Node> que; //定義隊列 24 node.x = i,node.y = j,node.layer = 0; 25 que.push(node); //入隊 26 inque[i][j] = true; //標記已經入隊 27 while(!que.empty()) { //隊列非空 28 Node top = que.front(); //取出隊首元素 29 que.pop(); //隊首元素出隊 30 if(top.x == T1 && top.y == T2) { //如果能到達終點 T 31 MIN = top.layer; 32 break; 33 } 34 for(int i = 0; i < 4; ++i) { //訪問相鄰的四個元素 35 int nowI = top.x + X[i]; 36 int nowJ = top.y + Y[i]; 37 if(judge(nowI,nowJ)) { 38 node.x = nowI,node.y = nowJ,node.layer = top.layer + 1; 39 que.push(node); //入隊 40 inque[nowI][nowJ] = true; //標記已經入隊 41 } 42 } 43 } 44 } 45 46 int main() { 47 cin>>m>>n; 48 for(int i = 0; i < m; ++i) { //初始化迷宮 49 for(int j = 0; j < n; ++j) 50 cin>>maze[i][j]; 51 } 52 cin>>S1>>S2>>T1>>T2; //起點(S1,S2)和終點(T1,T2) 53 BFS(S1,S2); //廣度優先搜索 54 cout<< (MIN <INF? MIN : -1); 55 return 0; 56 }
運行結果 1:
運行結果 2:
運行結果 3: