1. 程式人生 > >迷宮問題的求解(廣度優先搜索)

迷宮問題的求解(廣度優先搜索)

struct -o font 使用 sin 將在 地圖 數據 c++

迷宮問題很容易可以理解為廣度優先搜索問題,站在一個點上,首先試一試自己周圍的點是否可以走,如果是路則加入待走隊列,如果是墻則丟棄。迷宮問題在廣度優先搜索的時候需要特別註意的就是要及時拋棄,遇到走過的點立即丟棄,遇到墻立即丟棄,不然時間復雜度就很高。

題目描述

Ignatius被魔王抓走了,有一天魔王出差去了,這可是Ignatius逃亡的好機會.

魔王住在一個城堡裏,城堡是一個A*B*C的立方體,可以被表示成A個B*C的矩陣,剛開始Ignatius被關在(0,0,0)的位置,離開城堡的門在(A-1,B-1,C-1)的位置,現在知道魔王將在T分鐘後回到城堡,Ignatius每分鐘能從一個坐標走到相鄰的六個坐標中的其中一個.現在給你城堡的地圖,請你計算出Ignatius能否在魔王回來前離開城堡(只要走到出口就算離開城堡,如果走到出口的時候魔王剛好回來也算逃亡成功),如果可以請輸出需要多少分鐘才能離開,如果不能則輸出-1.

<center>技術分享圖片
</center>

輸入描述:

輸入數據的第一行是一個正整數K,表明測試數據的數量.每組測試數據的第一行是四個正整數A,B,C和T(1<=A,B,C<=50,1<=T<=1000),它們分別代表城堡的大小和魔王回來的時間.然後是A塊輸入數據(先是第0塊,然後是第1塊,第2塊......),每塊輸入數據有B行,每行有C個正整數,代表迷宮的布局,其中0代表路,1代表墻.(如果對輸入描述不清楚,可以參考Sample Input中的迷宮描述,它表示的就是上圖中的迷宮)
       

特別註意:本題的測試數據非常大,請使用scanf輸入,我不能保證使用cin能不超時.在本OJ上請使用Visual C++提交.

輸出描述:

對於每組測試數據,如果Ignatius能夠在魔王回來前離開城堡,那麽請輸出他最少需要多少分鐘,否則輸出-1.
       
示例1

輸入

1
3 3 4 20
0 1 1 1
0 0 1 1
0 1 1 1
1 1 1 1
1 0 0 1
0 1 1 1
0 0 0 0
0 1 1 0
0 1 1 0

輸出

11
這道題一開始看題看半天,其實它就是3*3*4=36個點,是一個立體的圖形,下面的0,1就是表示那個點是路還是墻
 1 #include<stdio.h>
 2 #include<queue>
 3 
 4 using namespace std;
 5 
 6 bool
mark[50][50][50]; //標記數組 7 int maze[50][50][50]; //保存立方體信息 8 9 struct Node 10 { 11 int x,y,z; 12 int t; 13 }; 14 queue<Node> Q; 15 16 int go[][3] 17 { 18 1,0,0, 19 -1,0,0, 20 0,1,0, 21 0,-1,0, 22 0,0,1, 23 0,0,-1 24 }; 25 26 int BFS(int a,int b,int c) 27 { 28 int i; 29 Node temp; 30 while( Q.empty()==false) 31 { 32 Node now = Q.front(); 33 Q.pop(); 34 for( i=0; i<6; i++) 35 { 36 //依次擴展6個相鄰結點 37 int nx = now.x+go[i][0]; 38 int ny = now.y+go[i][1]; 39 int nz = now.z+go[i][2]; 40 if( nx<0 || nx>=a || ny<0 || ny>=b || nz<0|| nz>=c) 41 continue; //若再立方體外則丟棄 42 if( maze[nx][ny][nz]==1) 43 continue; //若為墻則丟棄 44 if( mark[nx][ny][nz]==true) 45 continue; //若訪問過則丟棄 46 47 temp.x = nx; 48 temp.y = ny; 49 temp.z = nz; 50 temp.t = now.t+1; 51 Q.push(temp); //新位置加入隊列中 52 mark[nx][ny][nz] = true; //標記該位置 53 if( nx==a-1 && ny==b-1 && nz==c-1) 54 return temp.t; //到達終點 55 } 56 } 57 return -1; 58 } 59 int main() 60 { 61 int n; 62 int i,j,k; 63 int a,b,c,t; 64 int ret; 65 scanf("%d",&n); 66 while( n--) 67 { 68 69 scanf("%d%d%d%d",&a,&b,&c,&t); 70 for( i=0; i<a; i++) 71 { 72 for( j=0; j<b; j++) 73 { 74 for( k=0; k<c; k++) 75 { 76 scanf("%d",&maze[i][j][k]); 77 mark[i][j][k] = false; 78 } 79 } 80 } 81 while( Q.empty()==false) Q.pop(); //清空隊列 82 mark[0][0][0] = true; //標記起點 83 Node temp; 84 temp.t = temp.x = temp.y = temp.z=0; 85 Q.push(temp); 86 ret = BFS( a,b,c); 87 if( ret<=t) printf("%d\n",ret); //成功逃出輸出時間,無法找到終點輸出-1 88 else printf("-1\n"); //若時間超過返回-1 89 } 90 return 0; 91 }






迷宮問題的求解(廣度優先搜索)