题目大意:给一个三维迷宫,从(0,0,0)点能否在T时间内走到(a-1,b-1,c-1)点。
解题思路:基本的BFS的应用,注意BFS过程中对时间T的剪枝,如果超过T,则返回-1。因为是最短时间,因此要要判断该点是否被访问过。详见code。
题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=1253
code:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int MAXN = 55;
int map[MAXN][MAXN][MAXN];
int vis[MAXN][MAXN][MAXN];
int a,b,c,T,k,ex,ey,ez;
int dir[6][3]={{1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1}};
struct node{
int x,y,z,step;
};
int BFS(){
node s,t;
queue<node> q;
s.x=0;s.y=0;s.z=0;
s.step=0;
vis[s.x][s.y][s.z]=1;
q.push(s);
while(!q.empty()){
node tmp = q.front();
q.pop();
if(tmp.step>T) return -1; //进行剪枝
if(tmp.x==ex && tmp.y==ey && tmp.z==ez) return tmp.step; //满足条件则返回长度
for(int i=0;i<6;i++){ //进行六个方向的遍历
t.x=tmp.x+dir[i][0];
t.y=tmp.y+dir[i][1];
t.z=tmp.z+dir[i][2];
t.step=tmp.step+1;
if(t.x>=0 && t.x<a && t.y>=0 && t.y<b && t.z>=0 && t.z<c && !vis[t.x][t.y][t.z] && map[t.x][t.y][t.z]==0){ //进行条件判断
vis[t.x][t.y][t.z]=1;
q.push(t);
}
}
}
return -1;
}
int main(){
scanf("%d",&k);
while(k--){
memset(map,0,sizeof(map)); //初始化
memset(vis,0,sizeof(vis));
scanf("%d%d%d%d",&a,&b,&c,&T);
for(int i=0;i<a;i++)
for(int j=0;j<b;j++)
for(int z=0;z<c;z++){
scanf("%d",&map[i][j][z]);
}
ex=a-1;ey=b-1;ez=c-1; //获取终点
if(a+b+c-3>T) printf("-1\n"); //路径剪枝
int ans=BFS();
if(ans<=T && ans!=-1) printf("%d\n",ans);
else printf("-1\n");
}
return 0;
}