Fire!

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id

有一个人要从一个迷宫中逃出来,迷宫中‘#’表示不可走,‘.’表示可以走,但是迷宫失火了。火势以每秒向四周蔓延的速度蔓延。如果火已经蔓延到这里,人就不可走了,只要人走到迷宫的边缘就算成功逃出了。当然火无法蔓延到‘#’部分。问:至少需要几秒?注意火不是只有一个(我就是因为这个错了好多次);

思路:求一幅图,火势蔓延到该点的时间(BFS),然后直接BFS;就完成了。

#include <iostream>
#include <stdlib.h>
#include <cstdio>
#include <memory.h>
#include <queue>
#define maxn 1005
#define INF 10000005
using namespace std;
char map[maxn][maxn];
int MapTime[maxn][maxn];
int step[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
int T,M,N;
struct my
{
    int H,W,time;
}fire,men,now;
bool check(int H,int W)
{
    bool flag=0;
    fire.H=H;
    fire.W=W;
    fire.time=now.time+1;
    if(0<=H&&H<N&&0<=W&&W<M)
    {
        if(map[H][W]!='#')flag=1;
    }
    return flag;
}
void FireBFS()
{
    queue<my>Q;
    for(int i=0;i<N;i++)
    for(int j=0;j<M;j++)
    {
        MapTime[i][j]=INF;
        if(map[i][j]=='F')
        {
            fire.H=i,fire.W=j,fire.time=1;
            MapTime[fire.H][fire.W]=1;
            Q.push(fire);
        }
        if(map[i][j]=='J')men.H=i,men.W=j,men.time=1;
    }
    while(!Q.empty())
    {
        now=Q.front();
        Q.pop();
        for(int i=0;i<4;i++)
        {
            if(check(now.H+step[i][0],now.W+step[i][1]))
            {
                if(MapTime[fire.H][fire.W]==INF)
                {
                    MapTime[fire.H][fire.W]=fire.time;
                    Q.push(fire);
                }
            }
        }
    }
}
int BFS(my p)
{
    queue<my>Q;
    Q.push(p);
    while(!Q.empty())
    {
        now=Q.front();
        Q.pop();
        if(now.H==N-1||now.W==M-1||now.H==0||now.W==0)
		return now.time;
        for(int i=0;i<4;i++)
        {
            if(check(now.H+step[i][0],now.W+step[i][1])&&MapTime[fire.H][fire.W]>fire.time)
            {
                if(fire.H==N-1||fire.W==M-1||fire.H==0||fire.W==0)
			return fire.time;
                map[fire.H][fire.W]='#';
                Q.push(fire);
            }
        }
    }
    return -1;
}
int main()
{
   // freopen("in.txt","r",stdin);
    scanf("%d",&T);
    while(T--)
    {
        memset(MapTime,0,sizeof MapTime);
        memset(map,0,sizeof map);
        scanf("%d%d",&N,&M);
        for(int i=0;i<N;i++)
        scanf("%s",map[i]);
        FireBFS();
        map[men.H][men.W]='#';
        int a=BFS(men);
        if(a!=-1)printf("%d\n",a);
        else printf("IMPOSSIBLE\n");
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值