胜利大逃亡
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 21542 Accepted Submission(s): 8479
魔王住在一个城堡里,城堡是一个A*B*C的立方体,可以被表示成A个B*C的矩阵,刚开始Ignatius被关在(0,0,0)的位置,离开城堡的门在(A-1,B-1,C-1)的位置,现在知道魔王将在T分钟后回到城堡,Ignatius每分钟能从一个坐标走到相邻的六个坐标中的其中一个.现在给你城堡的地图,请你计算出Ignatius能否在魔王回来前离开城堡(只要走到出口就算离开城堡,如果走到出口的时候魔王刚好回来也算逃亡成功),如果可以请输出需要多少分钟才能离开,如果不能则输出-1.
特别注意:本题的测试数据非常大,请使用scanf输入,我不能保证使用cin能不超时.在本OJ上请使用Visual C++提交.
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 <cstdio>
#include <queue>
using namespace std;
int aa,bb,cc,map[55][55][55],visit[55][55][55],xx[6][3]={{1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1}};
//方向为前后,上下,左右
struct ssss
{
int a,b,c,x; //用结构体方便多个变量打包,a,b,c是三维坐标,x是走到这里的时间
}ss;
queue<ssss> q,qq; //能装打包好的结构体的队列,qq用来初始化q
void bfs()
{
while(!q.empty())
{
ss=q.front();q.pop();
//取出队首元素并删除
int i,a,b,c,A=ss.a,B=ss.b,C=ss.c;
ss.x+=10; //因为输入时是0和1,我要记录time,所以就一十一十地加了,嘿嘿
map[A][B][C]=ss.x;
//这里把当前就弄成ss.x,所以最后结果要-1,因为我的起点就是10
for(i=0;i<6;i++)
{
a=A+xx[i][0];
b=B+xx[i][1];
c=C+xx[i][2];
if(a>=0&&b>=0&&c>=0&&a<aa&&b<bb&&c<cc)
//判断是否过界
if(visit[a][b][c]&&map[a][b][c]!=1)
//判断是否访问过和是否是墙
{
ss.a=a;ss.b=b;ss.c=c;q.push(ss);visit[a][b][c]=0;
//打包,入队,标记已经访问
}
}
}
}
int main (void)
{
int T,t,i,j,k,l;
scanf("%d",&T);
while(T--&&scanf("%d%d%d%d",&aa,&bb,&cc,&t))
{
for(i=0;i<aa;i++)
for(j=0;j<bb;j++)
for(k=0;k<cc;k++)
scanf("%d",&map[i][j][k]),visit[i][j][k]=1;
q=qq;visit[0][0][0]=0;
//这里q=qq就可以看出qq用来给q初始化的作用了吧?标记map[0][0][0]为已经访问
ss.a=ss.b=ss.c=ss.x=0;q.push(ss);
//把map[0][0][0]打包入队
bfs();
k=map[aa-1][bb-1][cc-1];
//因为map[0][0][0]太长了,就用k取值,呵呵
if(k<10||k>(t+1)*10)printf("-1\n");
//如果没有走过,那么k一定是0或者1,因为起点就是10,而且是int,怕出问题就把除号改成乘号好点,别放了把总时间+1
else printf("%d\n",k/10-1);
//当然输出时的时间就得-1哦
}
return 0;
}