• 逃出升天


    题目链接:http://172.18.66.54:50015/problem.php?id=1466

    题目描述

        这里是一片n*m荒芜之体,穿过一个沼泽地就必须消耗一罐氧气(沼泽不会消失,没有氧气罐就不能穿过沼泽)。
    你是否能够逃出这里。
    '*':  空地
    '+':经过可以获得一罐氧气 (重复经过可以重复获得)
    '#':沼泽地(重复经过会重复消耗)
    'S':起点
    'T':终点
    你的背包最多带4罐氧气, 用掉可以继续获得。

    输入

    多样例(n, m输入为0 0结束)
    第一行:n m (n, m<=100)
    2-n行:输入地图。

    输出

    输出是否能够从起点到达终点
    是:"YES"并且输出最少的步数 
    否:  "NO"

    样例输入

    5 5
    S****
    +****
    +****
    #####
    ****T
    1 5
    +*S#T
    1 3
    S#T
    0 0
    

    样例输出 

    YES
    8
    YES
    6
    NO
    
    思路:Bfs跑一下就可以了。用dis[i][j][k]记录在位置(i, j)有k罐氧气的最少步数。如果下个状态(i, j, k)的步数< dis[i][j][k]就加入队列
    #include<bits/stdc++.h>
    using namespace std;
    const int  N=105;
    const int M=0x3f3f3f3f;
    int dp[N][N][8];
    char mp[N][N];
    int d[2][4]= {0,1,0,-1,1,0,-1,0};
    struct node
    {
      int x,y,n;//位置 x y 氧气瓶数 n
    };
    int main()
    {
      int i,j,n,m,t;
      int sx,sy,ex,ey;//起点 终点
      while(scanf("%d %d",&n,&m), n*m)
      {
        for(int i=1; i<=n; i++)
        {
          scanf("%s",mp[i]+1);
          for(int j=1; j<=m; j++)
          {
            if(mp[i][j]=='S') sx=i,sy=j;
            else if(mp[i][j]=='T') ex=i,ey=j;
            for(int k=0; k<=5; k++) dp[i][j][k]=M;//初始化
          }
        }
        queue<node>q;
        dp[sx][sy][0]=0;
        q.push(node{sx,sy,0});
        while(!q.empty())//BFS
        {
          node t=q.front();
          q.pop();
    
          for(int i=0; i<4; i++)//四个方向
          {
            int x=t.x+d[1][i];
            int y=t.y+d[0][i];
            int c=t.n;
            if(x>n||y>m||x<1||y<1) continue;//出界
            switch(mp[x][y])
            {
    
            case 'S'://起点
            case '*'://空地
              if(dp[x][y][c]>dp[t.x][t.y][c]+1)//秒数比较
              {
                dp[x][y][c]=dp[t.x][t.y][c]+1;
                q.push(node{x,y,c});
              }
              break;
            case 'T'://终点
              if(dp[x][y][c]>dp[t.x][t.y][c]+1)//秒数比较
              {
                dp[x][y][c]=dp[t.x][t.y][c]+1;
                q.push(node{x,y,c});
              }
              break;
            case '#'://毒气
              if(c>0&&dp[x][y][c-1]>dp[t.x][t.y][c]+1)//氧气瓶数>0 氧气瓶-1
              {
                dp[x][y][c-1]=dp[t.x][t.y][c]+1;
                q.push(node{x,y,c-1});
              }
              break;
            case '+'://氧气
              if(c<5&&dp[x][y][c+1]>dp[t.x][t.y][c]+1)//氧气瓶+1 秒数+1
              {
                dp[x][y][c+1]=dp[t.x][t.y][c]+1;
                q.push(node{x,y,c+1});
              }
              else if(c==4&&dp[x][y][c]>dp[t.x][t.y][c]+1)//不拿氧气瓶 比较秒数
              {
                dp[x][y][c]=dp[t.x][t.y][c]+1;
                q.push(node{x,y,c});
              }
              break;
            default://其他
              break ;
    
            }
          }
        }
        int ans=M;
        for(int k=0; k<=4; k++)//寻找终点最小值
          ans=min(ans,dp[ex][ey][k]);
    
        if(ans>=M)
        {
            printf("NO
    ");
        }
        else
        {
            printf("YES
    ");
            printf("%d
    ",ans);
        }
      }
    }
  • 相关阅读:
    系统兼容性与软件兼容性
    SqlServer 笔记三 规则
    Sql Server 2008 与 Visual Studio 2008 安装说明
    Ms Sql Server
    Git系列教程三 配置与基本命令
    Git系列教程一 入门与简介
    Git系列教程二 基础介绍
    浏览器IE与非IE区分
    SqlServer 笔记二 获取汉字的拼音首字母
    时间戳与日期字符串的转换
  • 原文地址:https://www.cnblogs.com/shmilky/p/14089037.html
Copyright © 2020-2023  润新知