1. 程式人生 > >九度1456勝利大逃亡【BFS】

九度1456勝利大逃亡【BFS】

pop 回來 每次 queue 方向 stream strong pac 測試

時間限制:1 秒

內存限制:128 兆

特殊判題:

提交:4432

解決:1616

題目描述:

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

輸入:

輸入數據的第一行是一個正整數K,表明測試數據的數量.每組測試數據的第一行是四個正整數A,B,C和T(1<=A,B,C<=50,1<=T<=1000),它們分別代表城堡的大小和魔王回來的時間.然後是A塊輸入數據(先是第0塊,然後是第1塊,第2塊......),每塊輸入數據有B行,每行有C個正整數,代表迷宮的布局,其中0代表路,1代表墻。

輸出:

對於每組測試數據,如果Ignatius能夠在魔王回來前離開城堡,那麽請輸出他最少需要多少分鐘,否則輸出-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

解題思路:

BFS:

技術分享

對狀態(x,y,z,time)的搜索,從初始狀態(0,0,0,0)開始,向六個合法方向拓展該點路徑,利用queue,每得到一個合法的新的狀態,就插入隊尾(push),然後每次從隊頭取出狀態進行拓展(front)。

代碼來源:王道機試指南

 1 #include<iostream>
 2 #include<queue>
 3 using namespace std;
 4 struct N{
 5     int x,y,z;
 6     int t;
 7 }; 
 8 bool mark[50][50][50];//標記數組 
 9 int
maze[50][50][50];//保存立方體信息 10 queue<N> Q; 11 int go[][3] = { //坐標變換數組 12 1,0,0, 13 -1,0,0, 14 0,1,0, 15 0,-1,0, 16 0,0,1, 17 0,0,-1, 18 }; 19 20 21 int BFS(int a, int b, int c){ 22 while (Q.empty() == false){ 23 N now = Q.front(); 24 Q.pop(); 25 for(int i=0;i<6;i++){ 26 int nx = now.x + go[i][0]; 27 int ny = now.y + go[i][1]; 28 int nz = now.z + go[i][2]; //得到新的坐標 29 if( nx<0||nx>=a||ny<0||ny>=b||nz<0||nz>=c){ //如果新坐標溢出,丟棄 30 continue; 31 } 32 if(maze[nx][ny][nz]==1) continue; //如果是墻,丟棄 33 if(mark[nx][ny][nz]==true) continue; //如果已經處理過該點,丟棄 34 N tmp; 35 tmp.x = nx; 36 tmp.y = ny; 37 tmp.z = nz; 38 tmp.t = now.t +1 ; 39 Q.push(tmp); 40 mark[nx][ny][nz] = true; 41 if(nx==a-1 && ny== b-1 && nz==c-1) return tmp.t; 42 } 43 } 44 return -1; 45 } 46 int main(){ 47 int n; 48 cin>>n; 49 while(n--){ 50 int a,b,c,t; 51 cin>>a>>b>>c>>t; 52 for(int i=0;i<a;i++){ 53 for(int j=0;j<b;j++){ 54 for(int k=0;k<c;k++){ 55 cin>>maze[i][j][k]; 56 mark[i][j][k] = false; 57 } 58 } 59 } 60 while(Q.empty() == false) Q.pop(); 61 mark[0][0][0] = true; 62 N tmp; 63 tmp.t=tmp.x=tmp.y=tmp.z=0; 64 Q.push(tmp); 65 int rec = BFS(a,b,c); 66 if(rec <= t) cout<<rec<<endl; 67 else cout<<-1<<endl; 68 69 } 70 return 0; 71 } 72

BFS經常用於最優值問題,比如迷宮問題,給出終點和起點,求最短路徑,為什麽用BFS到達終點時路徑就是最短的呢,想像樹的結構,BFS是從上到下一層層,的遍歷,所以當走到終點所在層時,搜索路徑肯定是最短的。

九度1456勝利大逃亡【BFS】