首页 > 代码库 > 九度1456胜利大逃亡【BFS】

九度1456胜利大逃亡【BFS】

时间限制: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】