1. 程式人生 > >勝利大逃亡,bfs,廣度優先搜索

勝利大逃亡,bfs,廣度優先搜索

地圖 cin 策略 mark 時間 -1 bfs 一個 bool

題目描述:

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
#include<iostream>
#include<stdio.h>
#include<queue>
using namespace std;
struct node{
    int x,y,z,t;
};
queue<node> q;
int maze[51
][51][51]; bool mark[51][51][51]; int go[6][3]={ 1,0,0, -1,0,0, 0,1,0, 0,-1,0, 0,0,1, 0,0,-1 };int BFS(int a,int b,int c){//廣搜傳遞的是終點,起點信息在main函數裏面加到隊列裏面 while(!q.empty()){ node temp=q.front(); q.pop(); for (int i=0;i<6;i++){ node np;
int xx=np.x=temp.x+go[i][0]; int yy=np.y=temp.y+go[i][1]; int zz=np.z=temp.z+go[i][2]; if (maze[xx][yy][zz] == 1 || mark[xx][yy][zz]==true) continue; if (xx<0||xx>=a||yy<0||yy>=b||zz<0||zz>=c) continue; np.t=temp.t+1; q.push(np); mark[np.x][np.y][np.z]=true; if (np.x==a-1 && np.y==b-1&&np.z==c-1) return np.t; } } return -1; } int main (){ int k,a,b,c,t; cin>>k; while (k--){ cin>>a>>b>>c>>t; for (int i=0;i<a;i++){ for (int j=0;j<b;j++){ for (int k=0;k<c;k++){ cin>>maze[i][j][k]; mark[i][j][k]=false; } } } while (!q.empty()) q.pop(); mark[0][0][0]=true; node temp; temp.t=temp.x=temp.y=temp.z=0; q.push(temp); int ans; ans=BFS(a,b,c); ans = ans<=t?ans:-1; cout<<ans<<endl; } return 0; }

廣搜:

  1. go數組,大一做題時學長就用,但是自己覺得不用,其實很好啊。
  2. bfs傳遞的是終點坐標
  3. 突然發現這個bfs跟liao神講的搜索剪枝一樣啊,怪當年愚鈍不會寫代碼啊
  4. 這個bfs的剪枝策略是用了mark數組,標記之前到達過該點否,到過了就不用去了,因為時間會比之前到達的時間長
  5. 用四元組,xyzt記錄信息,成為節點

勝利大逃亡,bfs,廣度優先搜索