北京2018网络赛A题

题意:给你一个迷宫,迷宫有开始节点和结束节点,问你从开始走到结束的最小时间,其中,#代表这个点有毒气,身上必须带着氧气瓶才行,B代表每次进入这个点可以带一个氧气瓶,最多身上带五个,P代表进入这个点加速,不耗费时间

解题思路:就是bfs+优先队列,就是氧气瓶的地方麻烦点,我们只需要对于每个点,用一个多余的状态标记进入这个点身上氧气瓶的数量就可以了

代码:

#include<bits/stdc++.h>
using namespace std;
struct node
{
    int x,y,step,cnt;

    node(int _x=0,int _y=0,int _step=0,int _cnt=0):x(_x),y(_y),step(_step),cnt(_cnt){}
    friend bool operator<(node a,node b)
    {
        return a.step>b.step;
    }
}tmp,now;
char s[110][110];
int n,m,sx,sy;
int next1[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
int visit[110][110][10];
int bfs(int x,int y)
{
    priority_queue<node>que;
    que.push(node(x,y,0,0));
    while(!que.empty())
    {
        now=que.top();que.pop();
        if(s[now.x][now.y]=='T')
            return now.step;
        for(int i=0;i<4;i++)
        {

            tmp.x=now.x+next1[i][0];tmp.y=now.y+next1[i][1];
            if(tmp.x<1||tmp.x>n||tmp.y<1||tmp.y>m)
                continue;
            if(s[tmp.x][tmp.y]=='B')
            {
                tmp.cnt=min(5,now.cnt+1);tmp.step=now.step+1;
                if(!visit[tmp.x][tmp.y][tmp.cnt])
                {
                    visit[tmp.x][tmp.y][tmp.cnt]=1;
                    que.push(tmp);
                }
            }
            else if(s[tmp.x][tmp.y]=='P')
            {
                tmp.cnt=now.cnt;tmp.step=now.step;
                if(!visit[tmp.x][tmp.y][tmp.cnt])
                {
                    visit[tmp.x][tmp.y][tmp.cnt]=1;
                    que.push(tmp);
                }
            }
            else if(s[tmp.x][tmp.y]=='#')
            {
                tmp.cnt=now.cnt-1;tmp.step=now.step+2;
                if(tmp.cnt<0)
                    continue;
                if(!visit[tmp.x][tmp.y][tmp.cnt])
                {
                    visit[tmp.x][tmp.y][tmp.cnt]=1;
                    que.push(tmp);
                }
            }
            else
            {
                tmp.cnt=now.cnt;tmp.step=now.step+1;
                if(!visit[tmp.x][tmp.y][tmp.cnt])
                {
                    visit[tmp.x][tmp.y][tmp.cnt]=1;
                    que.push(tmp);
                }
            }
        }

    }
    return -1;
}
int main()
{
    while(cin>>n>>m&&n&&m)
    {
        memset(visit,0,sizeof(visit));
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
        {
            cin>>s[i][j];if(s[i][j]=='S'){sx=i;sy=j;}
        }
        int ans=bfs(sx,sy);
        cout<<ans<<endl;
    }
}

 

posted @ 2019-04-19 21:43  荒岛的龟  阅读(159)  评论(0编辑  收藏  举报