/*
分析:
犯2了,也不知道怎么想的,我竟然让每两组输出
之间输出一空行PE了。。。估计是题做串了吧- -I,
不过,说实话啊,看见PE,咱就放心啦~~~
我的1a啊~
说不清楚,我提供几组测试吧,自己弄的:
111
3 1
3
2
4
Ans:1
3 3
3 0 0
2 0 0
4 0 0
Ans:1
3 3
3 0 1
1 2 1
4 0 1
Ans:-1
3 6
1 1 1 1 1 1
0 0 0 1 0 0
0 0 2 4 0 3
Ans:5
5 7
1 1 1 0 1 1 1
1 1 1 0 1 1 1
3 0 0 2 0 0 0
1 1 1 0 1 1 1
1 1 1 4 1 1 1
Ans:-1
5 7
1 1 1 0 1 1 1
1 1 1 0 1 1 1
3 0 0 2 0 0 0
1 1 1 0 0 1 1
1 1 1 4 1 1 1
Ans:3
2012-07-24
分析:
犯2了,也不知道怎么想的,我竟然让每两组输出
之间输出一空行PE了。。。估计是题做串了吧- -I,
不过,说实话啊,看见PE,咱就放心啦~~~
我的1a啊~
说不清楚,我提供几组测试吧,自己弄的:
111
3 1
3
2
4
Ans:1
3 3
3 0 0
2 0 0
4 0 0
Ans:1
3 3
3 0 1
1 2 1
4 0 1
Ans:-1
3 6
1 1 1 1 1 1
0 0 0 1 0 0
0 0 2 4 0 3
Ans:5
5 7
1 1 1 0 1 1 1
1 1 1 0 1 1 1
3 0 0 2 0 0 0
1 1 1 0 1 1 1
1 1 1 4 1 1 1
Ans:-1
5 7
1 1 1 0 1 1 1
1 1 1 0 1 1 1
3 0 0 2 0 0 0
1 1 1 0 0 1 1
1 1 1 4 1 1 1
Ans:3
2012-07-24
*/
#include"stdio.h"
#include"string.h"
#include"queue"
using namespace std;
int n,m;
int map[10][10];
int flag[10][10];
int hash[9][9][9][9];
int x_s_box,y_s_box,x_s_per,y_s_per;
int x_e,y_e;
int dir[4][2]={1,0, -1,0, 0,1, 0,-1};
struct A
{
int x,y;
};
struct node
{
int i;
int step;
struct A box;
struct A per;
};
int judge_per_1(int x,int y)
{
if(x<0 || x>=n || y<0 || y>=m) return 1;
if(flag[x][y]==1) return 1;
return 0;
}
int judge_per(int x_s,int y_s,int x_e,int y_e)
{
queue<A>q;
A cur,next;
int i,l;
for(i=0;i<n;i++)
for(l=0;l<m;l++)
flag[i][l]=map[i][l];
cur.x=x_s;
cur.y=y_s;
flag[cur.x][cur.y]=1;
q.push(cur);
while(!q.empty())
{
cur=q.front();
q.pop();
if(cur.x==x_e && cur.y==y_e) return 1;
for(i=0;i<4;i++)
{
next.x=cur.x+dir[i][0];
next.y=cur.y+dir[i][1];
if(judge_per_1(next.x,next.y)) continue;
flag[next.x][next.y]=1;
q.push(next);
}
}
return 0;
}
int judge_box(int x,int y)
{
if(x<0 || x>=n || y<0 || y>=m) return 0;
if(map[x][y]) return 0;
return 1;
}
int BFS()
{
queue<node>q;
node cur,next;
int i;
int f1,f2;
cur.box.x=x_s_box;
cur.box.y=y_s_box;
cur.per.x=x_s_per;
cur.per.y=y_s_per;
cur.step=0;
for(i=0;i<4;i++)
{
if(cur.box.x-cur.per.x==dir[i][0] && cur.box.y-cur.per.y==dir[i][1])
{
cur.i=i;
break;
}
}
hash[cur.per.x][cur.per.y][cur.box.x][cur.box.y]=1;
q.push(cur);
while(!q.empty())
{
cur=q.front();
q.pop();
if(cur.box.x==x_e && cur.box.y==y_e) return cur.step;
for(i=0;i<4;i++)
{
f1=f2=0;
if(cur.i==i)f1=1;
else
{
map[cur.box.x][cur.box.y]=1;
f1=judge_per(cur.per.x,cur.per.y, cur.box.x-dir[i][0],cur.box.y-dir[i][1]);
map[cur.box.x][cur.box.y]=0;
}
if(!f1) continue;
next.box.x=cur.box.x+dir[i][0];
next.box.y=cur.box.y+dir[i][1];
f2=judge_box(next.box.x,next.box.y);
if(!f2) continue;
next.per.x=cur.box.x;
next.per.y=cur.box.y;
if(hash[next.per.x][next.per.y][next.box.x][next.box.y]) continue;
hash[next.per.x][next.per.y][next.box.x][next.box.y]=1;
next.i=i;
next.step=cur.step+1;
q.push(next);
}
}
return -1;
}
int main()
{
int T,Case=0;
int i,l;
int ans;
int f1;
int aim_x,aim_y;
scanf("%d",&T);
while(T--)
{
if(Case) printf("\n");
Case=1;
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
for(l=0;l<m;l++)
{
scanf("%d",&map[i][l]);
if(map[i][l]==2) {x_s_box=i;y_s_box=l; map[i][l]=0;}
else if(map[i][l]==3) {x_e=i;y_e=l; map[i][l]=0;}
else if(map[i][l]==4) {x_s_per=i;y_s_per=l; map[i][l]=0;}
}
f1=0;
for(i=0;i<4;i++)
{
if(x_s_box-x_s_per==dir[i][0] && y_s_box-y_s_per==dir[i][1])
{
f1=1;
break;
}
}
if(!f1)
{
map[x_s_box][y_s_box]=1;
for(i=0;i<4;i++)
{
aim_x=x_s_box+dir[i][0];
aim_y=y_s_box+dir[i][1];
f1=judge_per(x_s_per,y_s_per,aim_x,aim_y);
if(f1)
{
x_s_per=aim_x;
y_s_per=aim_y;
break;
}
}
map[x_s_box][y_s_box]=0;
}
if(!f1) {printf("-1\n");continue;}
memset(hash,0,sizeof(hash));
ans=BFS();
printf("%d\n",ans);
}
return 0;
}