UVA - 11624 Fire! bfs

题目链接

题意:有一个迷宫,迷宫里有多个火堆和一个人,每一分钟人可以移动一个单元格,同时每堆火焰可以同时向上下左右四个方向移动,每分钟火堆先移动,且人不能移动到有火堆的单元格,求人能否逃离迷宫且若能逃离则最短用时是多少。

思路:典型的bfs,由于火堆和人都要扩展,且火堆每分钟要比人先移动,则初始化时,我们可以先把火堆放入队列中再放入人,这样每分钟总能先扩展完所有火堆的移动,再扩展人的移动。之后就是模板题了。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<map>
#include<vector>
#include<queue>
#include<deque>
using namespace std;
#define ll long long
#define PI acos(-1)
#define INF 0x3f3f3f3f
#define NUM 33010
#define debug true
#define lowbit(x) ((-x)&x)
#define ffor(i,d,u) for(int i=(d);i<=(u);++i)
#define _ffor(i,u,d) for(int i=(u);i>=(d);--i)
#define mst(array,Num,Kind,Count) memset(array,Num,sizeof(Kind)*(Count))
const int P = 1e9+7;
int T;
int n,m;
char ma[1005][1005];
int check[1005][1005];
int h[4]={0,0,1,-1},l[4]={-1,1,0,0};
struct node
{
    int flag;
    int posx,posy;
    int step;
};
queue < node > q;
template <typename T>
void read(T& x)
{
    x=0;
    char c;T t=1;
    while(((c=getchar())<'0'||c>'9')&&c!='-');
    if(c=='-'){t=-1;c=getchar();}
    do(x*=10)+=(c-'0');while((c=getchar())>='0'&&c<='9');
    x*=t;
}
template <typename T>
void write(T x)
{
    int len=0;char c[21];
    if(x<0)putchar('-'),x*=(-1);
    do{++len;c[len]=(x%10)+'0';}while(x/=10);
    _ffor(i,len,1)putchar(c[i]);
}
inline bool bfs()
{
    node t1,t2;
    int x,y;
    while(!q.empty())
    {
        t1 = q.front(),q.pop();
        if(t1.flag == 2&&(t1.posx == 1||t1.posx == n||t1.posy == 1||t1.posy == m))
        {
            write(t1.step+1);
            putchar('\n');
            return false;
        }
        t2 = t1;
        ++t2.step;
        ffor(i,0,3)
        {
            x = t1.posx+h[i],y = t1.posy+l[i];
            if(x < 1||x > n||y < 1||y > m||ma[x][y] == '#')continue;
            if(t1.flag == 1&&check[x][y] != 1)
            {
                check[x][y] = 1;
                t2.posx = x,t2.posy = y;
                q.push(t2);
            }
            if(t1.flag == 2&&check[x][y] != 1&&check[x][y] !=2)
            {
                check[x][y] = 2;
                t2.posx = x,t2.posy = y;
                q.push(t2);
            }
        }
    }
    return true;
}
void AC()
{
    node x;
    read(T);
    int pos1,pos2;
    while(T--)
    {
        read(n),read(m);
        x.step = 0;
        x.flag = 1;
        while(!q.empty())q.pop();
        ffor(i,1,n)
        {
            ffor(j,1,m)
            {
                ma[i][j] = getchar();
                check[i][j] = 0;
                if(ma[i][j] == 'F')
                {
                    x.posx = i,x.posy = j;
                    check[i][j] = 1;
                    q.push(x);
                }
                if(ma[i][j] == 'J')pos1 = i,pos2 = j,check[i][j] = 2;
            }
            getchar();
        }
        x.posx = pos1,x.posy = pos2;
        x.flag = 2;
        q.push(x);
        if(bfs())puts("IMPOSSIBLE");
    }
}
int main()
{
    AC();
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值