Fire! UVA - 11624

Fire! UVA - 11624

Joe works in a maze. Unfortunately, portions of the maze havecaught on re, and the owner of the maze neglected to create a reescape plan. Help Joe escape the maze.Given Joe’s location in the maze and which squares of the mazeare on re, you must determine whether Joe can exit the maze beforethe re reaches him, and how fast he can do it.Joe and the re each move one square per minute, vertically orhorizontally (not diagonally). The re spreads all four directionsfrom each square that is on re. Joe may exit the maze from anysquare that borders the edge of the maze. Neither Joe nor the remay enter a square that is occupied by a wall.

Input

The first line of input contains a single integer, the number of testcases to follow. The rst line of each test case contains the twointegersRandC, separated by spaces, with 1R;C1000. ThefollowingRlines of the test case each contain one row of the maze. Each of these lines contains exactlyCcharacters, and each of these characters is one of:
#, a wall
., a passable square
J, Joe’s initial position in the maze, which is a passable square
F, a square that is on reThere will be exactly oneJin each test case.

Output

For each test case, output a single line containing `IMPOSSIBLE’ if Joe cannot exit the maze before the re reaches him, or an integer giving the earliest time Joe can safely exit the maze, in minutes.

Sample Input
 2
 4 4
 ####
 #JF#
 #..#
 #..#
 3 3
 ###
 #J.
 #.F
Sample Output
 3
 IMPOSSIBLE

先说思路:火的位置不止一个,先记录火的位置,然后遍历,记录火蔓延至其他位置所用的时间。之后bfs求最短路径,并把到达某格所用的时间与火蔓延至该格的时间作比较,若大于等于,则不能到达该位置。
还有,每组数据输入运行结束后要清空队列。
本来是用一个bfs,队列每循环一次,就让火蔓延一次。先逃跑后蔓延。代码写出来后发现若到达某处所用时间与火蔓延所用时间相等的话行不通,遂转变思路。

#include<iostream>
#include<cstring>
#include<queue>
#include<vector>
#include<cstdio>
using namespace std;

const int maxn=1010;
char a[maxn][maxn];
int tim[maxn][maxn];//火蔓延至某处所用的时间 
int n,m,a1,a2,ans;
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
int flag;
bool vis[maxn][maxn];//标记 

struct node{
	int x,y;
	int step;//时间 
};
queue<node>q;

bool judge(int x,int y)
{
	if(x<0||y<0||x>=n||y>=m)
	{
		return false;
	}
	if(a[x][y]=='#'||vis[x][y])
	{
		return false;
	}
	return true;
}

void fire()//判断火蔓延至某处所用时间,并存起来 
{
	node cur,next;
	while(!q.empty())
	{
		cur=q.front();
		q.pop();
		for(int i=0;i<4;i++)
		{
			int nx=cur.x+dx[i];
			int ny=cur.y+dy[i];
			if(!judge(nx,ny))
			{
				continue;
			}
			next.x=nx;
			next.y=ny;
			next.step=cur.step+1;
			q.push(next);
			vis[nx][ny]=true;
			tim[nx][ny]=next.step;
		}
	}
	return;
}

void bfs()
{
	node cur,next;
	cur.x=a1,cur.y=a2,cur.step=0;
	q.push(cur);
	vis[cur.x][cur.y]=true;
	while(!q.empty())
	{
		cur=q.front();
		q.pop();
		if(cur.x==0||cur.y==0||cur.x==n-1||cur.y==m-1)
		{
			flag=1;
			ans=cur.step+1;
			return;
		}
		for(int i=0;i<4;i++)
		{
			int nx=cur.x+dx[i];
			int ny=cur.y+dy[i];
			if(!judge(nx,ny)||cur.step+1>=tim[nx][ny])
			{
				continue;
			}
			next.x=nx;
			next.y=ny;
			next.step=cur.step+1;
			vis[nx][ny]=true;
			q.push(next);
		}
	}
	return;
}

int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		flag=0;
		node cur;
		cin>>n>>m;
		int i,j;
		for(i=0;i<n;i++)
		{
			for(j=0;j<m;j++)
			{
				cin>>a[i][j];
				if(a[i][j]=='F')
				{
					cur.x=i;
					cur.y=j;
					cur.step=0;
					vis[cur.x][cur.y]=true;
					q.push(cur);//把火的位置入队 
				}
				if(a[i][j]=='J')
				{
					a1=i;
					a2=j;
				}
			}
		}
		fill(tim[0],tim[0]+maxn*maxn,100000);//开始时火蔓延至某处的时间为无穷 
		memset(vis,0,sizeof(vis));
		fire();
		memset(vis,0,sizeof(vis));//初始化vis 
		bfs();
		if(flag)	cout<<ans<<endl;
		else	cout<<"IMPOSSIBLE"<<endl;
		while(!q.empty())//清空队列 
		{
			q.pop();
		}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值