zoukankan      html  css  js  c++  java
  • FJUT 1676 QAQ和迷宫(BFS+优先队列)

    QAQ和迷宫

    TimeLimit: 2000/1000 MS (Java/Others)  MemoryLimit: 32768/32768 K (Java/Others)
    64-bit integer IO format:%I64d
    收藏题目
    Problem Description
    QAQ被围困在一个神奇的迷宫里,迷宫里有一些墙不能行走,但是迷宫里有一些墙已经很脆弱了,可以直接拆掉,但是拆一面墙必须花费d的时间,那么QAQ要逃离这个迷宫至少需要多少时间?
    Input
    输入的第一行是t表示测试数据的组数,每组格式如下
    1. 第一行是三个整数 h, w (3 <= h;w <= 500), 和 d (0 <= d <= 50), 地图的高度和宽度,以及拆掉一格可以拆的墙的时间
    2.然后是h行w列的地图,地图内容如下
    ―"S"表示出发点
    ―"."表示平地,走过需要花费1的时间
    ―"#"表示不能拆的墙,不能走
    ―"@"表示可以拆掉的墙,可以花费d的时间拆掉
    全地图被不能拆的墙(也就是"#")包围,只有一个出口。
    Output
    每组测试数据输出一个整数,表示走出地图所需要的最短时间。
    QAQ教你广搜进阶
    一般的广搜是将可行状态加入容器Q,然后每次取出最先进入Q的状态进行扩展,然后把扩展的状态依次加入Q。
    而对于每个状态的权值不同的情况下,不应该是从Q拿出最先进入的状态,而是取出当前距离开始点最近的状态进行扩展。
    这样的话,每次取出的状态就是依次递增的状态了。
    
    SampleInput
    16
    11
    5

    分析:求两点间最短时间的走法,考虑BFS,
    走到'@'所需要的时间是d+1,走到'.'需要的时间是1
    所以我们在用BFS的时候,进行入队操作的时候,可能用时间多的,会被先放入.
    但是我们每次都应从最小的时间进行扩展,使得时间呈现递增状态
    这样先取到的,时间就一定小.
    所以采用优先队列,队列里储存结构体,使得每次取的都是耗时最少的

    需要注意的是定义优先队列,重载运算符时,'<'表示最大值优先,而'>'
    表示最小值优先.- -(一开始在这个地方弄错了,耽误了好多时间)
    代码如下:
    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <vector>
    #include <stack>
    using namespace std;
    int map1[510][510];
    int dir[4][2]={1,0,-1,0,0,1,0,-1};
    int sx,sy,ex,ey;
    int row,col,d;
    int vis[510][510];
    int check(int x,int y)
    {
        if(x>=0&x<row&&y>=0&&y<col&&!vis[x][y]&&map1[x][y]!='#')return 1;
        return 0;
    }
    struct node
    {
        int x;
        int y;
        int step;
    };
    struct Cmp
    {
        bool operator()(const node &x,const node  &y){
            return x.step>y.step;
        }
    };
    priority_queue<node,vector<node>,Cmp> Q;
    int  bfs()
    {
       node a,next;
       a.x=sx;
       a.y=sy;
       a.step=0;
       Q.push(a);
       while(!Q.empty())
       {
         a=Q.top();
        // cout<<a.step<<endl;
        //   printf("%d %d
    ",a.x,a.y);
         Q.pop();
         if(a.x==ex&&a.y==ey)return a.step;
         for(int i=0;i<4;i++)
         {
             next.x=a.x+dir[i][0];
             next.y=a.y+dir[i][1];
         //   cout<<next.x<<" "<<next.y<<endl;
             if(check(next.x,next.y))
             { //cout<<next.x<<" "<<next.y<<endl;
                 vis[next.x][next.y]=1;
               if(map1[next.x][next.y]=='.')
               {
                 next.step=a.step+1;
                 Q.push(next);
               }
               else
               {
                   next.step=a.step+d+1;
                   Q.push(next);
               }
             }
         }
       }
       return -1;
    }
    int main()
    {
      int t,ans;
      scanf("%d",&t);
      while(t--)
      {
          while(!Q.empty())
            Q.pop();
          memset(vis,0,sizeof(vis));
          scanf("%d%d%d",&row,&col,&d);
          for(int i=0;i<row;i++)
            for(int j=0;j<col;j++)
          {
            scanf(" %c",&map1[i][j]);
            if(map1[i][j]=='S')
            {
             sx=i;
             sy=j;
            }
            if(i==0||i==row-1)
            {
             if(map1[i][j]!='#'){
              ex=i;
              ey=j;}
            }
    
               if(j==0||j==col-1)
            {
             if(map1[i][j]!='#'){
              ex=i;
              ey=j;}
            }
          }
          vis[sx][sy]=1;
           ans=bfs()+1;
           printf("%d
    ",ans);
      }
    }


  • 相关阅读:
    <整理> 在Bash中添加个人定制的命令
    <整理> linux常用命令及工具
    论文分享:目标检测-YOLO
    Siamese Attentional Keypoint Network for High Performance Visual Tracking--论文笔记
    ubuntu 相关软件设置
    anoconda 神经网络 相关操作
    转载:决策树算法梳理
    转载:XGBOOST算法梳理
    XGB算法梳理
    决策树算法梳理
  • 原文地址:https://www.cnblogs.com/a249189046/p/7454158.html
Copyright © 2011-2022 走看看