UVA11624 Fire! (两点广搜BFS)

39 阅读1分钟

题目:

\

\

思路:

给了很多个火(F)和一个人(J),火和人想四面蔓延的速度都是1,问人能否走出迷宫,思路是先给地图外围加一圈点来判断是否走出迷宫,然后把人的位置和火焰的位置都记录下来,先让火焰入队,最后让人入队,用两个标记数组来标记火和人是否有走过或者烧过,因为火可以烧人走过的,

'#'代表墙

'.'代表路

'F'代表火

'J'代表人

代码:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
char map[1005][1005];
int vis[1005][1005];//火烧
int vix[1005][1005];//人走
int go[4][2]= {{0,1},{0,-1},{-1,0},{1,0}};//四个方向
int m,n,num,x1,y1;
struct node
{
    int x,y,s,id;//人的id为0,火的id为1
} a[1000];
int bfs(int num)
{
    node now,to;
    queue<node>q;
    for(int i=0; i<num; i++)
    {
        q.push(a[i]);
        vis[a[i].x][a[i].y]=1;//先把火焰入队,并且标记烧过的
    }
    q.push(a[num]);
    vix[a[num].x][a[num].y]=1;//把人入队,标记走过的
    while(!q.empty())
    {
        now=q.front();
        if(now.id==0&&(now.x<1||now.y<1||now.x>n||now.y>m))return now.s;//当走出迷宫时返回步数
        for(int i=0; i<4; i++)
        {
            to.x=now.x+go[i][0];
            to.y=now.y+go[i][1];
            to.s=now.s+1;
            to.id=now.id;
            if(to.id==0&&vix[to.x][to.y]==0&&vis[to.x][to.y]==0&&map[to.x][to.y]=='.')//如果是人,当且仅当火没烧过,人没走过时,可以继续搜下去
            {
                vix[to.x][to.y]=1;//人走过标记为1
                q.push(to);
            }
            if(to.id==1&&vis[to.x][to.y]==0&&to.x>0&&to.x<=n&&to.y>0&&to.y<=m&&map[to.x][to.y]=='.')//判断是否越界,及能不能继续烧
            {
                vis[to.x][to.y]=1;//火烧过的标记
                q.push(to);
            }
        }
        q.pop();
    }
    return 0;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        mem(map,0);
        mem(vis,0);
        mem(vix,0);//初始化
        num=0;
        scanf("%d%d",&n,&m);
        for(int i=1; i<=n; i++)
        {
            scanf("%s",map[i]+1);
            for(int j=1; j<=m; j++)
            {
                if(map[i][j]=='F')//找到火焰
                {
                    a[num].x=i;
                    a[num].y=j;
                    a[num].id=1;
                    a[num].s=0;
                    num++;
                }
                if(map[i][j]=='J')//找到人
                {
                    x1=i;
                    y1=j;
                }
            }
        }
        a[num].x=x1;
        a[num].y=y1;
        a[num].s=0;
        a[num].id=0;
        for(int i=0; i<=n+1;i++)//外边围一圈点
        {
            map[i][0]='.';
            map[i][m+1]='.';
        }
        for(int i=0; i<=m+1; i++)
        {
            map[0][i]='.';
            map[n+1][i]='.';
        }
        int ans=bfs(num);
        if(ans)
            printf("%d\n",ans);
        else
            printf("IMPOSSIBLE\n");
    }
    return 0;
}


\