/*
hdu 1253 经典:三维BFS+剪枝
ymc 2008/09/18
题目大意:
三维地图A×B×C,0代表路,1代表0。人在S(0,0,0),出口在E(A-1,B-1,C-1)。
求人能否在T时间能达到出口,以及最短时间。
分析与解题思路:
经典的BFS,但是不剪枝会TLE。
剪枝方法:每次搜索到一个新的点P1(x1,y1,z1)的时候,设S到P1的距离
为SP1,P1到E的估计最短距离为P1E。若SP1+P1E>T,剪枝。
*/
#include <iostream>
#include <queue>
using namespace std;
const int N=55;
int map[N][N][N];
int dist[N][N][N];
int A,B,C,T;
int step[6][3]={{1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1}};
void BFS()
{
memset(dist,-1,sizeof(dist));
dist[0][0][0]=0;
queue<int> q;
q.push(0);q.push(0);q.push(0);
int x,y,z,x1,y1,z1;
int tmp;
while(!q.empty())
{
x=q.front();q.pop();
y=q.front();q.pop();
z=q.front();q.pop();
if(x==A-1&&y==B-1&&z==C-1)
return;
if(dist[x][y][z]>T)//剪枝
return;
for(int k=0;k<6;k++)
{
x1=x+step[k][0];
y1=y+step[k][1];
z1=z+step[k][2];
if(x1<0||x1>=A||y1<0||y1>=B||z1<0||z1>=C)
continue;
if(map[x1][y1][z1]==1||dist[x1][y1][z1]>=0)
continue;
dist[x1][y1][z1]=dist[x][y][z]+1;
tmp=A+B+C-x1-y1-z1-3;
if(tmp+dist[x1][y1][z1]<=T)//剪枝,重要,不然TLE
{
q.push(x1),q.push(y1),q.push(z1);
}
}
}
}
int main()
{
int test;
scanf("%d",&test);
while(test-->0)
{
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 k=0;k<C;k++)
scanf("%d",&map[i][j][k]);
BFS();
if(dist[A-1][B-1][C-1]>T||dist[A-1][B-1][C-1]==-1)//可能会是T+1
printf("-1\n");
else
printf("%d\n",dist[A-1][B-1][C-1]);
}
}