hdu1254

/*
分析:
    犯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;
}











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值