NC14608 after与迷宫 bfs

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
4 4 4 3
..**
*F..
*.*.
*M.F

输出

14

典型的bfs例题,但是它的题目意思真的很迷哇,看了别人对题目的解读才发现:同时经过Y,K才会变成超级YK机器人。

所以我们的解题思路就可以变成走只有F的长度和走只有W的长度进行对比。

#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<algorithm>
using namespace std;
char a[2002][2002];
int dist[2002][2002],dis[2002][2002];
int dx[]={-1,0,0,1},dy[]={0,1,-1,0};
int t;
int n,m,r,c;
typedef pair<int,int> PII;
int bfs()
{
    queue<PII> q;
    memset(dist,-1,sizeof dist);
    dist[1][1]=0;
    q.push({1,1});
    while(q.size())
    {
        auto t=q.front();
        q.pop();
        for(int i=0;i<4;i++)
        {
            int xx=t.first+dx[i],yy=t.second+dy[i];
            if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&dist[xx][yy]==-1&&a[xx][yy]!='*'&&a[xx][yy]!='M')
            {
                dist[xx][yy]=dist[t.first][t.second]+1;
                q.push({xx,yy});
            }
        }
    }
    return dist[r][c];
}
int bfs2()
{
    queue<PII> p;
    memset(dis,-1,sizeof dis);
    dis[1][1]=0;
    p.push({1,1});
    while(p.size())
    {
        auto t=p.front();
        p.pop();
        for(int i=0;i<4;i++)
        {
            int xx=t.first+dx[i],yy=t.second+dy[i];
            if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&dis[xx][yy]==-1&&a[xx][yy]!='*'&&a[xx][yy]!='F')
            {
                dis[xx][yy]=dis[t.first][t.second]+1;
                p.push({xx,yy});
            }
        }
    }
    return dis[r][c];
}
int main()
{
    //cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
    cin>>t;
    while(t--)
    {
        cin>>n>>m>>r>>c;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                cin>>a[i][j];
        bfs();
        bfs2();
        /*for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                cout<<dist[i][j]<<" ";
            }
            cout<<endl;
        }*/
        //cout<<dist[r][c]<<" "<<dis[r][c]<<endl;
        if(dist[r][c]==-1&&dis[r][c]==-1) cout<<"IMPOSSIBLE"<<endl;
        else if(dist[r][c]!=-1&&dis[r][c]==-1) cout<<dist[r][c]*2<<endl;
        else cout<<dis[r][c]*2<<endl;
    }
    return 0;
}

图论我真的是太菜了,揪心😟 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Vijurria

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值