UVA Fire!(两点BFS)

46 篇文章 0 订阅

Fire!

原题链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=&problem=2671&mosmsg=Submission+received+with+ID+18577889

题意:一个迷宫中有多处地方起火,问,人能不能在火烧到之前走出迷宫,如果能,则输出最短的时间思路:我们可以把起火的位置和人的位置存起来,然后一一压入队列中(要最后存入人的位置,这样才能够判断人下一步能不能走),另外就是在外围在加上一圈点,这样以便与判断人走出迷宫。


注意:火和人的下一步的判断标准不同,所以设了两个标记变量。

ps:比较坑的是一开始没看清题,没看出是多个地点着火敲打,最后在UVA的Udebug中给的样例中才发现。。。0.0多读题

代码:

#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
struct node
{
    int x,y,step,ic;//ic记录身份
} w[1000];
int vis[1010][1010];//记录火烧过的
int vix[1010][1010];//记录人走过的
char s[1010][1010];
int go[4][2]= {0,1,0,-1,1,0,-1,0};
int n,m;
int bfs(int sum)
{
    memset(vix,0,sizeof(vix));
    memset(vis,0,sizeof(vis));
    queue<node>q;
    node a,b;
    for(int i=0;i<sum;i++)//火的位置入队
    {
        q.push(w[i]);
        vis[w[i].x][w[i].y]=1;
    }
    q.push(w[sum]);//人的位置入队
    vix[w[sum].x][w[sum].y]=1;
    while(!q.empty())
    {
        a=q.front();
        if(a.ic==0)
        {
            if(a.x<=0||a.x>n||a.y<=0||a.y>m)
                return a.step;
        }
        for(int i=0; i<4; i++)
        {
            b.x=a.x+go[i][0];
            b.y=a.y+go[i][1];
            b.step=a.step+1;
            b.ic=a.ic;
            if(b.ic==0)
            {
                if(!vix[b.x][b.y]&&s[b.x][b.y]=='.'&&!vis[b.x][b.y])
                {
                    vix[b.x][b.y]=1;
                    q.push(b);
                }
            }
            else if(b.ic==1)
            {
                if(!vis[b.x][b.y]&&s[b.x][b.y]=='.'&&b.x>0&&b.x<=n&&b.y>0&&b.y<=m)
                {
                    vis[b.x][b.y]=1;
                    q.push(b);
                }
            }
        }
        q.pop();
    }
    return -1;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int i,j,x,y,sum=0;
        scanf("%d%d",&n,&m);

        for(i=1; i<=n; i++)
        {
            scanf("%s",s[i]+1);
            for(j=1; j<=m; j++)
            {
                if(s[i][j]=='F')
                    w[sum].x=i,w[sum].y=j,w[sum].step=0,w[sum].ic=1,sum++;//火的身份是1
                else if(s[i][j]=='J')
                    x=i,y=j;
            }
        }
        w[sum].x=x,w[sum].y=y,w[sum].step=0,w[sum].ic=0;//人的身份是0
         for(i=0;i<=n+1;i++)//在外围加一圈
            s[i][0]='.',s[i][m+1]='.';
        for(j=0;j<=m+1;j++)
            s[0][j]='.',s[n+1][j]='.';
        int ans=bfs(sum);
        if(ans==-1)
            printf("IMPOSSIBLE\n");
        else
            printf("%d\n",ans);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值