NC15665 maze

题目链接

题目链接

题意

小明来到一个由n x m个格子组成的迷宫,有些格子是陷阱,用’#‘表示,小明进入陷阱就会死亡,’.'表示没有陷阱。小明所在的位置用’S’表示,目的地用’T’表示。

小明只能向上下左右相邻的格子移动,每移动一次花费1秒。

有q个单向传送阵,每个传送阵各有一个入口和一个出口,入口和出口都在迷宫的格子里,当走到或被传送到一个有传送阵入口的格子时,小明可以选择是否开启传送阵。如果开启传送阵,小明就会被传送到出口对应的格子里,这个过程会花费3秒;如果不开启传送阵,将不会发生任何事情,小明可以继续向上下左右四个方向移动。

一个格子可能既有多个入口,又有多个出口,小明可以选择任意一个入口开启传送阵。使用传送阵是非常危险的,因为有的传送阵的出口在陷阱里,如果小明使用这样的传送阵,那他就会死亡。也有一些传送阵的入口在陷阱里,这样的传送阵是没有用的,因为小明不能活着进入。请告诉小明活着到达目的地的最短时间。

思路

  • 带传送带的走迷宫,由于传送带的存在可能使步数无序,可使用优先队列

参考代码

#include<bits/stdc++.h>
using namespace std;
char aa[510][510];
int  vis[510][510];
int  yd[4][2]= {{1,0},{-1,0},{0,1},{0,-1}};
vector< pair<int, int> > transmit[510][510];
int sx,sy;
struct node
{
    int x,y,bs;
    node(int _x = 0, int _y = 0, int _bs = 0): x(_x), y(_y), bs(_bs) {}
    bool operator < (const node &s) const
    {
        return bs > s.bs;
    }
};
priority_queue<node>q;
int main()
{
    int n,m,t;
    while(cin>>n>>m>>t)
    {
        while(!q.empty())
            q.pop();
        for(int i = 1; i <= n; i++)
        {
            for(int j = 1; j <= m; j++)
            {
                transmit[i][j].clear();vis[i][j] = 0;
            }
        }
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=m; j++)
            {
                cin>>aa[i][j];
                if(aa[i][j]=='S')
                {
                    sx=i;
                    sy=j;
                }
            }
        }
        int tmpx1,tmpy1,tmpx2,tmpy2;
        for(int i=0; i<t; i++)
        {
            cin>>tmpx1>>tmpy1>>tmpx2>>tmpy2;
            transmit[tmpx1+1][tmpy1+1].push_back({tmpx2+1, tmpy2+1});
        }
        q.push(node(sx, sy, 0));
        for(int i = 0; i < transmit[sx][sy].size(); i++)
        {
            int xx = transmit[sx][sy][i].first, yy = transmit[sx][sy][i].second;
            if(!vis[xx][yy] && aa[xx][yy] != '#' && xx >= 1 && yy <= n && xx >= 1 && yy <= m)
            {
                q.push(node(xx, yy, 3));
            }
        }
        int fl=0;
        while(!q.empty())
        {
            node tmp=q.top();
            q.pop();
            if(vis[tmp.x][tmp.y])
                continue;
            vis[tmp.x][tmp.y] = 1;
            if(aa[tmp.x][tmp.y]=='T')
            {
                fl=1;
                cout<<tmp.bs<<endl;
                break;
            }
            int x,y;
            for(int i=0; i<4; i++)
            {
                x=tmp.x+yd[i][0];
                y=tmp.y+yd[i][1];
                if(x>=1&&x<=n&&y>=1&&y<=m&&vis[x][y]==0&&aa[x][y]!='#')
                {
                    for(int j = 0; j < transmit[x][y].size(); j++)
                    {
                        int xx = transmit[x][y][j].first, yy = transmit[x][y][j].second;
                        if(!vis[xx][yy] && aa[xx][yy] != '#' && xx >= 1 && xx <= n && yy >= 1 && yy <= m)
                        {
                            q.push(node(xx, yy,  tmp.bs + 4));
                        }
                    }
                    q.push(node(x, y, tmp.bs + 1));
                }
            }
        }
        if(fl==0)
            cout<<-1<<endl;
    }

}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

hlee-top

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

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

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

打赏作者

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

抵扣说明:

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

余额充值