这道题本身是不难的,套用bfs模板就行。可是就是因为自己的一点点小疏忽,把一个x错写成了y,导致找了半天的BUg,苦恼苦恼。。。(大伙们一定要仔细啊!!)
题目描述
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<math.h>
#include<queue>
#include<stack>
using namespace std;
//对于BFS来说,需要有队列的参与,每次都是进队,同理这道题的bfs的参数是三个坐标,但是会在队列中多一个时间的坐标,用来表示现在走了多久
//每次进队列的时候,都是之前那个队列出来的时间加一
//然后当然还需要一个三维数组来存xyz,和一个数组来判断有没有被访问过
int map[50][50][50];
bool make[50][50][50];//一个是用以输入,一个是用以判断
int a,b,c,t;//表示的就是坐标位置
//然后创建一个结构体用来存数据
struct M{
int x,y,z,t;//分别代表三个坐标和时间
};
bool judge(int x,int y,int z){
//写一个判断是否可以选这个位置的函数
//把越界单独写出来吧
if(x<0||x>=a||y<0||y>=b||z<0||z>=c)
return false;
if(map[x][y][z]==0&&make[x][y][z]==false)
return true;//如果这个地方是路,并且没有被访问过
return false;
}
//还要写三个数组用来(其实直接用一个二维数组就行)
int stepx[6]={0,0,0,0,1,-1};
int stepy[6]={0,0,1,-1,0,0};
int stepz[6]={1,-1,0,0,0,0};
int BFS(int x,int y,int z,int t){
//这里返回值是int 因为需要返回对应的时间
//首先让他进队吧,可是这个时间怎么算呢,那我的想法就是这里再加一个时间
//先创建一个队列
queue<M> q;
M temp;
temp.x=x;
temp.y=y;
temp.z=z;
temp.t=t;
//然后让这个temp进队列
q.push(temp);
while(!q.empty()){
//在他非空的情况之下,然后删去队头
temp=q.front();//取出对头元素
//这里可以有一个判断
if(temp.x==a-1&&temp.y==b-1&&temp.z==c-1)
return temp.t;
q.pop();
// printf("%d%d%d ",temp.x,temp.y,temp.z);
for(int i=0;i<6;i++){
//开始判断这几个位置
int newx=temp.x+stepx[i];
int newy=temp.y+stepy[i];
int newz=temp.z+stepz[i];
// printf("%d%d%d ",newx,newy,newz);
if(judge(newx,newy,newz)){
//如果这个合理的话,那就,把他的t加一,并且加入队列,这里创建了一个新的结构体,用来加入队列,还要出示话
make[newx][newy][newz]=true;
M gg;
gg.x=newx;
gg.y=newy;
gg.z=newz;//找了半天,问题在这啊!!
gg.t=temp.t+1;//这里是需要注意的
//然后入队
q.push(gg);
}
}
}
return -1;
}
int main()
{
int k,time;
scanf("%d",&k);
while(k--){
scanf("%d%d%d%d",&a,&b,&c,&time);
//开始初始化
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]);
make[i][j][z]=false;
}
//然后开始先把第一个位置设置成访问过了
make[0][0][0]=true;
int re=BFS(0,0,0,0);
if(re<=time)
printf("%d\n",re);
else
printf("-1\n");
}
//debug发现从000出发之后,就一个点有效,然后之后就没用了,我知道了,还有一个k没有写!,然后还有问题。。
}