hdu2531

/*
分析:
    广搜,小变异。
    抽象压缩,以点带面。
虽然因为一个判断条件写错了而没有1A,不过好赖思路是
自己的,还是很happy的O(∩_∩)O~


                                            2012-05-23
*/










#include"stdio.h"
#include"string.h"
int map[111][111];                       //0空地、1是目标、-1是障碍
int flag[111][111];                      //1代表该位置可以呆、0表示不可以
int form[22][22];                        //一个二维表格,记录形状,1表示有、0表示没有
int step[111][111];                      //步数
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
struct A
{
	int x;
	int y;
}Q[10011];
int main()
{
	int h,w;
	int h2,w2;
	int i,l;
	int d;
	int next_x,next_y;
	int temp1,temp2;
	int i1,i2,l1,l2;
	int up,low,left,right;
	int k1,key;
	int ans;
	char str[111];
	while(scanf("%d%d",&h,&w),h||w)
	{
		///map
		up=low=-10;
		left=1111;
		right=-10;
		for(i=0;i<h;i++)
		{
			scanf("%s",str);
			for(l=0;str[l];l++)
			{
				if(str[l]=='.')			map[i][l]=0;
				else if(str[l]=='O')	map[i][l]=-1;
				else if(str[l]=='Q')	map[i][l]=1;
				else if(str[l]=='D')	map[i][l]=2;
				if(str[l]=='D')
				{
					if(up==-10)	up=i;
					if(i>low)	low=i;
					if(l<left)	left=l;
					if(l>right)	right=l;
				}
			}
		}
		///form
		h2=low-up+1;
		w2=right-left+1;
		for(i1=0,i2=up;i1<h2;i1++,i2++)
		for(l1=0,l2=left;l1<w2;l1++,l2++)
		{
			if(map[i2][l2]==2)
			{
				form[i1][l1]=1;
				map[i2][l2]=0;
			}
			else	form[i1][l1]=0;
		}
		///flag
		for(i=0;i<h;i++)
		{
			for(l=0;l<w;l++)
			{
				d=1;
				for(i1=0;i1<h2;i1++)
				{
					for(l1=0;l1<w2;l1++)
					{
						if(form[i1][l1]==0)	continue;
						temp1=i+i1;
						temp2=l+l1;
						if(temp1<0||temp1>=h||temp2<0||temp2>=w)		{d=0;break;}
						if(map[temp1][temp2]!=0&&map[temp1][temp2]!=1)	{d=0;break;}
					}
					if(d==0)break;
				}
				if(d==0)flag[i][l]=0;
				else	flag[i][l]=1;
			}
		}
		///BFS
		ans=0;
		key=1;
		k1=0;
		Q[0].x=up;
		Q[0].y=left;
		flag[up][left]=1;
		for(i=0;i<h;i++)
		for(l=0;l<w;l++)
			step[i][l]=-1;
		step[Q[0].x][Q[0].y]=0;
		while(k1<key)
		{


			for(i1=0;i1<h2;i1++)
			{
				for(l1=0;l1<w2;l1++)
				{
					if(form[i1][l1]==0)	continue;
					if(map[Q[k1].x+i1][Q[k1].y+l1]==1)	{ans=1;break;}
					if(ans)	break;
				}
				if(ans)	break;
			}
			if(ans)	break;


			for(i=0;i<4;i++)
			{
				next_x=Q[k1].x+dir[i][0];
				next_y=Q[k1].y+dir[i][1];
				if(step[next_x][next_y]!=-1)continue;
				if(flag[next_x][next_y]!=1)	continue;
				if(next_x<0||next_x>=h||next_y<0||next_y>=w)	continue;
				step[next_x][next_y]=step[Q[k1].x][Q[k1].y]+1;
				Q[key].x=next_x;
				Q[key].y=next_y;
				key++;
			}
			k1++;
		}
		///结果
		if(ans)	printf("%d\n",step[Q[k1].x][Q[k1].y]);
		else	printf("Impossible\n");
	}
	return 0;
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值