HDOJ 2364 Escape

  这个题虽说是一个简单的BFS问题,但是耗费了我好长时间,而且AC的是相当蛋疼。关键注意几下几点:

1:血的教训:可能初始位置即为出口位置(即初始就在房间的边缘),此时所用时间为0.

2:每一个格子要保存是从哪个方向到达的。也就是曾经有哪一个方向到达了它,只有曾经在某个方向从没到达过它,这时才入栈...

3:再就是不能回头。

 

AC代码:
#include<iostream>
#include<queue>
using namespace std;

char map[85][85];
int data[85][85][4];
int directx[4]={1,0,-1,0};
int directy[4]={0,1,0,-1};

typedef struct{
	int x,y,direction,time;
}Node;

int BFS(int h,int w,int ex,int ey)
{
	if((ex==0) || (ex==h-1) || (ey==0) || (ey==w-1))
		return 0;
	
	queue<Node> Q;
	Node node,node1;
	int dx,dy,dtime,ddrection;
	node.x=ex;
	node.y=ey;
	node.time=0;
	node.direction=-1;
	Q.push(node);
	
	while(!Q.empty())
	{
		node=Q.front();
		Q.pop();
		
		for(int i=0;i<4;++i)
		{
			if(i%2==0 && (node.direction)%2==0)
			{
				
				if((map[node.x+directx[1]][node.y+directy[1]]!='#') ||(map[node.x+directx[3]][node.y+directy[3]]!='#'))
					continue;
			}
			else if(i%2==1 && (node.direction)%2==1)
			{
				if((map[node.x+directx[0]][node.y+directy[0]]!='#') || (map[node.x+directx[2]][node.y+directy[2]]!='#'))
					continue;
			}
			if((node.direction%2==i%2) && (node.direction!=i))//判断不能回头
				continue;
			dx=node.x+directx[i];
			dy=node.y+directy[i];
			dtime=node.time+1;
			ddrection=i;
			if(dx>=0 && dx<h && dy>=0 && dy<w)
			{
				if((map[dx][dy]=='.') && ((dx==0) || (dx==h-1) || (dy==0) || (dy==w-1)))
					return dtime;	
				if(map[dx][dy]=='#')
					continue;
				
				node1.x=dx;
				node1.y=dy;
				node1.time=dtime;
				node1.direction=ddrection;
				
				if(!data[dx][dy][ddrection])
				{
					data[dx][dy][ddrection]=1;
					Q.push(node1);
				}		
			}			
		}
	}
	return -1;
}
int main()
{
	int t,h,w,ex,ey;
	cin>>t;
	while(t--)
	{
		memset(map,0,sizeof(map));
		memset(data,0,sizeof(data));
		cin>>h>>w;
		for(int i=0;i<h;++i)
		{
			for(int j=0;j<w;++j)
			{
				cin>>map[i][j];
				if(map[i][j]=='@')
				{
					ex=i;
					ey=j;
				}
				
			}
		}
		cout<<BFS(h,w,ex,ey)<<endl;
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值