bfs fire 题解

题目:

小明最后也没能进入游戏大厂,也没能娶到心爱的女孩,现在小明在一家迷宫里工作。
不幸的是,迷宫里因为线路老化而发生了火灾。小明现在需要一个逃跑路线,请你帮助倒霉的小明从迷宫中逃离出去吧
小明在迷宫中编号为 J 的位置,根据小明在迷宫中的位置以及迷宫中着火的位置(F),你必须确定在火焰烧到小明之前,他是否能逃离迷宫,如果能,他能多快逃离。
小明每分钟移动一个方格(上、下、左、右四个方向中的一个),但是火焰一分钟能向四个方向同时蔓延。小明可以从迷宫的任何一个边界逃离。无论是小明还是火都不会到达有墙的位置。。

输入:

输入的第一行包含一个整数,即测试数
每个测试用例的第一行包含两个整数R和C,用空格分隔,1≤ R、 C≤ 1000
以下R行中的每一行都包含C个字符,每个字符都是以下字符之一:

#,一堵墙
.,空地,小明和火都可以通过
J,小明在迷宫中的初始位置
F,着火的广场

每个测试用例中只有一个J。

输出:

对于每个测试用例,如果小明不能在火烧到之前退出迷宫,则输出一行 “IMPOSSIBLE”
如果能逃出迷宫,则输出小明最快可以在几分钟内安全的逃出迷宫,每组输出占一行

思路:主要利用广搜的思想,将火的每一轮扩散加入队列,再判断人能走的位置,将可以走的位置加入队列,如果人走的位置最终可以越出输出范围,即视为逃脱成功。注意一点,火应该优先于人,才可以判断人之后可以走的路程,一定先将火的数据加入队列,再判断人是否可以逃脱。

代码:

#include<bits/stdc++.h>
using namespace std;
int sx,sy;
struct node
{
	int x,y,step;
	int flag;
}sc;
queue<node> q;
int dir[4][2]={0,1,0,-1,1,0,-1,0};
int book[1005][1005];//记录人走的 
char mp[1005][1005];//地图 
int n,m;
int bfs()
{
	node head,next;
	memset(book,0,sizeof(book));//多组输入记得每组数据清零 
	sc.x=sx;//把人的数据加入队列 
	sc.y=sy;
	sc.step=0;
	sc.flag=0;
	q.push(sc);
	while(!q.empty())
	{
		head=q.front();
		q.pop();
		if(head.flag==1)//将火扩散的情况加入队列 
		{
			for(int i=0;i<4;i++)
			{
				int tx=head.x+dir[i][0];
				int ty=head.y+dir[i][1];
				if(tx<0||tx>=n||ty<0||ty>=m||mp[tx][ty]=='#'||mp[tx][ty]=='F')
				continue;
				mp[tx][ty]='F';
				next.x=tx;
				next.y=ty;
				next.step=head.step+1; 
				next.flag=1;
				q.push(next);
			}
		}
		else//将人能走的位置加入队列 
		{
			for(int i=0;i<4;i++)
			{
				int tx=head.x+dir[i][0];
				int ty=head.y+dir[i][1];
				if(tx<0||tx>=n||ty<0||ty>=m)
				{
					
					return head.step+1;
				}
				if(mp[tx][ty]=='#'||mp[tx][ty]=='F'||book[tx][ty])
				continue;
				book[tx][ty]=1;
				next.x=tx;
				next.y=ty;
				next.flag=0;
				next.step=head.step+1;
				q.push(next);
			}
		}
	}
	
	return 0;
}
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		while(!q.empty())//清空队列 
		q.pop();
		memset(book,0,sizeof(book));
		cin>>n>>m;
		for(int i=0;i<n;i++)
			for(int j=0;j<m;j++)
			{
				cin>>mp[i][j];
				if(mp[i][j]=='J')
				{
					sx=i;
					sy=j;
				}
				if(mp[i][j]=='F')
				{
					sc.x=i;
					sc.y=j;
					sc.step=0;
					sc.flag=1;
					q.push(sc);
				}
			}
		
		int ans=bfs();
		if(ans)
		cout<<ans<<endl;
		else
		cout<<"IMPOSSIBLE"<<endl;
	}
} 

题目本身不难,但数据量有点大,要对每一个细节检查到位(对自己说的,别介)。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值