//简单的广度优先搜索
//解题思路:剪枝
//*思路首先分析可走的路的总数是否大于等于最短路径数(最短路径数=a+b+c-2),如果小于怎样都无法到达出口
//*所以可以直接输出-1,还有总的时间数小于最短时间(最短时间数=a+b+c-2)也是无法到达出口,除去以上情况
//*然后使用BFS进行搜寻就可以了
#include <stdio.h>
#include <queue>
using namespace std;
#define arraysize 101
int dir[6][3]={{1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1}}; //搜索的六个方向
int map[arraysize][arraysize][arraysize];
int A,B,C,T;
int mintime;
typedef struct node
{
int x;
int y;
int z;
int time;
}node;
queue<node> myqueue;
void BFS()
{
int i,j;
while(!myqueue.empty()) //此处一定别忘了在广度优先搜索之前将队列置空,因为这wa了n次
myqueue.pop ();
node frontnode,nextnode;
frontnode.x = 0;
frontnode.y = 0;
frontnode.z = 0;
frontnode.time = 0;
map[0][0][0] = 1;
myqueue.push(frontnode);
while(!myqueue.empty())
{
frontnode = myqueue.front();
myqueue.pop();
for(i=0;i<6;++i)
{
nextnode.x = frontnode.x +dir[i][0];
nextnode.y = frontnode.y +dir[i][1];
nextnode.z = frontnode.z +dir[i][2];
nextnode.time = frontnode.time +1;
if(nextnode.x >=0 && nextnode.x <A && nextnode.y >=0 && nextnode.y <B && nextnode.z >=0 && nextnode.z <C && map[nextnode.x][nextnode.y][nextnode.z]!=1)
{
if(nextnode.x == A-1 && nextnode.y == B-1 && nextnode.z == C-1 && nextnode.time<=T)
{
printf("%d\n",nextnode.time);
return ;
}
map[nextnode.x][nextnode.y][nextnode.z] = 1; //此处进行改变,代表该点加入到了队列中
myqueue.push(nextnode);
}
}
}
printf("-1\n");
}
int main()
{
//freopen("1.txt","r",stdin);
int num = 0; //记录可走的路数
int K;
int n,i,j,k;
scanf("%d",&K);
for(n=0;n<K;++n)
{
scanf("%d%d%d%d",&A,&B,&C,&T);
for(i=0;i<A;++i)
{
for(j=0;j<B;++j)
{
for(k=0;k<C;++k)
{
scanf("%d",&map[i][j][k]);
if(map[i][j][k] == 0)
num++;
}
}
}
if(num<A+B+C-2 || T<A+B+C-2) //此处注意剪枝
{
printf("-1\n");
continue;
}
BFS();
}
return 0;
}