【牛客基础】after与迷宫(bfs+理解题目)

链接:https://ac.nowcoder.com/acm/problem/14608
来源:牛客网

题目描述

after的算法书的遗落在一个叫做AIJ的迷宫中了,这个迷宫有N*M个房间,迷宫的入口为(1,1),算法书遗落在(r,c)。迷宫中的房间有四种状态:空房间、无法进入的房间、有墨菲斯托存在的房间和有莉莉丝存在的房间。墨菲斯托会否定一切,而莉莉丝会诱惑人做一种叫做YK的活动。after是一个意志薄弱的人,他遇到了墨菲斯托和莉莉丝之后,便会变成眼神空洞的超级YK机器人。after每步可以从他当前的房间走至上下左右四个房间的其中一个房间。after害怕变成超级YK机器人,所以要尽快拿到算法书然后从入口逃离。问after最少需要走多少步才可以在不变成超级YK机器人的情况下从入口出发取回算法书并逃离迷宫?

输入描述:

第一行一个正整数T(T<=10),表示共有T组数据。
对于每组数据,第一行四个正整数N,M,r,c(1<=N,M<=1000;1<=r<=N;1<=c<=M)。
接下来N行,每行M个字符,每个表示房间的状态,“.”表示空房间,“*”表示无法进入的房间,“F”表示有墨菲斯托存在的房间,“M”表示有莉莉丝存在的房间。
数据保证(1,1)为“.”。
输出描述:
对每组数据输出一行,即after最少需要走的步数。若after无法取回算法书,则输出“IMPOSSIBLE”(不带引号)。

示例1

输入

1
4 4 4 3
…**
*F…
..
*M.F

输出

14

【想说的】:这个题目不太难,就是理解题目意思有点那啥,记录一下。题目的意思就是说,M,F不能同时走。那么可以先把F当作空地bfs求路径,然后再把M当空地。最后分情况讨论即可。

题解

#include<bits/stdc++.h>
using namespace std;
const int maxn=1002;
char ymp[maxn][maxn];
int mp[maxn][maxn];
int d[maxn][maxn];
int n,m,tx,ty;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
queue<int> que;
void bfs()
{
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
        {
            d[i][j]=-1;
        }
    while(!que.empty())
        que.pop();
    d[0][0]=0;
    que.push(0);
    while(que.size())
    {
        int tem=que.front();
        que.pop();
        int x=tem/m;
        int y=tem%m;
        for(int i=0;i<4;i++)
        {
            int nx=x+dx[i];
            int ny=y+dy[i];
            if(nx<0||nx>=n||ny<0||ny>=m||d[nx][ny]!=-1)
                continue;
            if(mp[nx][ny]!=1)
                continue;

            d[nx][ny]=d[x][y]+1;
            que.push(nx*m+ny);

        }
    }
   return ;

}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
            scanf("%d%d%d%d",&n,&m,&tx,&ty);
            tx--;
            ty--;

                for(int i=0;i<n;i++)
                {
                    for(int j=0;j<m;j++)
                    {

                        scanf(" %c",&ymp[i][j]);
                    }
                }
                for(int i=0;i<n;i++)
                {
                    for(int j=0;j<m;j++)
                    {
                        if(ymp[i][j]=='.')
                            mp[i][j]=1;
                        if(ymp[i][j]=='*')
                            mp[i][j]=0;
                        if(ymp[i][j]=='F')
                            mp[i][j]=1;
                        if(ymp[i][j]=='M')
                            mp[i][j]=0;
                    }
                }
                int k1=-1,k2=-1;
                bfs();
                 k1=d[tx][ty];
                for(int i=0;i<n;i++)
                {
                    for(int j=0;j<m;j++)
                    {
                        if(ymp[i][j]=='M')
                            mp[i][j]=1;
                        if(ymp[i][j]=='F')
                            mp[i][j]=0;
                    }
                }

                bfs();
                k2=d[tx][ty];

                if(k1==-1&&k2!=-1)
                  cout<<k2*2<<endl;
                else if(k1!=-1&&k2==-1)
                    cout<<k1*2<<endl;
                else if(k1!=-1&&k2!=-1)
                    cout<<min(k1,k2)*2<<endl;
                else
                {
                    cout<<"IMPOSSIBLE"<<endl;
                }


    }
   return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值