zoukankan      html  css  js  c++  java
  • UESTC_Just a Maze CDOJ 1162

    Just a Maze

    Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 262144/262144KB (Java/Others)
     

    Here is a maze with N × M room.

    You start from the room (SR,SC) and want to go to the room located at (TR,TC). However, there are many traps and monsters in this maze.

    There are 4 types of rooms:

    1. Blank->('.'). which has nothing.
    2. Rock->('#'). which you can not enter it.
    3. Trap->('a'~'z'), which once you enter it, you will suffer (Trap-'a'+1) damage(s). After you leave,the trap will reset so it can be triggered next time.
    4. Monster->('A'~'Z'). If you go into a monster room or any room adjacent to a monster room, the monster will immediately rush up to you and fight with you. You will kill it, but you will get hurt too, suffering (Monster-'A'+1) damage(s). And the monster will not revive.

    Two rooms are adjacent if and only if they share an edge. You can take 1 step to go from a room to another adjacent room.

    The safest path is a lowest total damage path. Among all safest path,find the path with lowest steps.

    Input

    The first line contains two integers N and M (1N,M500).

    The second line contains 4 integers SR,SC,TR,TC (1SR,TRN and 1SC,TCM).

    For the next N lines, each line contains M characters indicating the map of maze. Each type of room is marked as:

    1. Blank->('.')
    2. Rock->('#')
    3. Trap: from 'a'~'z'
    4. Monster: from 'A'~'Z'

    The damage you suffer from the trap 'a' is 1,'b' is 2..and so on.

    The damage you suffer from the monster 'A' is 1... and 'Z' is 26.

    The room (SR,SC) and (TR,TC) are always blank rooms and will not be adjacent to any monster room.

    Output

    Output the lowest total damage and the lowest steps in all safest path.

    Sample input and output

    Sample InputSample Output
    3 5
    1 1 3 5
    ..b..
    .zC#.
    ..a..
    4 6

    Source

    2015 UESTC ACM Summer Training Team Selection (4)
     
    解题报告:
     本题的难点在于如何建图,普通简图的话会受到多次伤害(就是怪物不死的问题)
    因为有个条件是怪物不相邻,那么我们就给怪物所在的附近的 4 个格子全部建边(每个格子可以通往另外3个格子),同时我们知道这个时间代价是 2
    处理好这个之后,我们考虑如何处理伤害的问题
    我们定义Damge( i , j ) 表示从格子i 到 格子j所受的伤害(这个移动只能是相邻的或者通过上面建的边)
    Damage(i ,j ) = Damge(j) - ( i , j )之间共享的怪兽的伤害
    然后本题就完了
    注意不要使用spfa,不要使用spfa,不要使用spfa,重要的事说三遍
    请使用dijkstra的堆优化!!
     
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <vector>
    #include <stack>
    #include <map>
    #include <set>
    #include <queue>
    #define pb push_back
    #define show(x) cout << "x is " << x << endl
    #define printarray(x,n) for(int i = 0 ; i < n ; ++ i) x == 0 ? cout << x[i] : cout << x[i] << " ";cout << endl
    #define input_fast std::ios::sync_with_stdio(false);std::cin.tie(0)
    #define local freopen("in.txt","r",stdin)
    #define loop(x,st,ed) for(int x = st ; x < ed ; ++ x)
    #define blackkey
    typedef long long ll;
    using namespace std;
    const int maxn = 500 + 50;
    
    typedef struct status
    {
      int x , y  ;
      status(int x, int y )
       {
          this->x = x, this->y = y ;
       }    
    };
    
    typedef struct Edge
    {
      int x , y , co;
      Edge(int x, int y , int co)
       {
          this->x = x , this->y = y , this->co = co;
       }
    };
    
    typedef struct qst
    {
      int x , y , d1 , d2;
      friend bool operator < (const qst & a , const qst & b)
       {
             if (a.d1 < b.d1)
              return false;
             else if(a.d1 == b.d1 && a.d2 < b.d2)
              return false;
             return true;
       }    
      qst(int x,int y,int d1,int d2)
       {
            this-> x = x , this->y = y , this->d1 = d1 , this->d2 = d2;
       }
    };
    
    
    typedef pair<int,int>pos;
    typedef pair<pos,pos>spj;
    int n , m , sr , sc , tr , tc , mincost[maxn][maxn][2] , dir[4][2] = {-1,0,1,0,0,1,0,-1} , damage[maxn][maxn] , ban[maxn][maxn] , damage2[maxn][maxn] ,used[maxn][maxn] ;  
    char s[maxn][maxn];
    vector<Edge>E[maxn][maxn];
    set<spj>sb;
    priority_queue<qst>q;
    
    inline int inmap(int x,int y)
    {
       return x <= n && x >= 1 && y <= m && y >= 1;
    }
    
    int GetSameDamage(int x1,int y1,int x2,int y2)
    {
       int ans = 0;
       loop(i , 0 , 4)
        {
            int newx = x1 + dir[i][0];
            int newy = y1 + dir[i][1];
            if (s[newx][newy] <= 'Z' && s[newx][newy] >= 'A')
             {
                 loop(j , 0 , 4)
                  if (x2 + dir[j][0] == newx && y2 + dir[j][1] == newy)
                   {
                        ans += s[newx][newy] - 'A' + 1;
                        break;
                  }
             }
        }
       return ans;
    }
    
    
    void dijkstra()
    {
      q.push(qst(sr,sc,0,0));
      memset(mincost,-1,sizeof(mincost));
      mincost[sr][sc][0] = mincost[sr][sc][1] = 0;
      while(!q.empty())
       {
             int x = q.top().x , y = q.top().y , d1 = q.top().d1 , d2 = q.top().d2 ; q.pop();
             if (used[x][y])
              continue;
             used[x][y] = 1;
             loop(i , 0 , 4)
             {
                  int newx = x + dir[i][0] , newy = y + dir[i][1] ;
                  if (!inmap(newx,newy) || ban[newx][newy]) continue;
                 int newhurt = d1 + damage[newx][newy] + damage2[newx][newy] , newcost = d2 + 1;
                 if ( newhurt < mincost[newx][newy][0] || !(mincost[newx][newy][0] ^ -1)  )
                  {
                       mincost[newx][newy][0] = newhurt;
                       mincost[newx][newy][1] = newcost;
                       q.push(qst(newx,newy,newhurt,newcost));
                  }
                 else if( !(newhurt ^ mincost[newx][newy][0]) && newcost < mincost[newx][newy][1])
                  {
                        mincost[newx][newy][1] = newcost;
                        q.push(qst(newx,newy,newhurt,newcost));
                  }
             }
          loop(i , 0 , E[x][y].size() )
             {
                  int newx = E[x][y][i].x , newy = E[x][y][i].y , add = E[x][y][i].co;
                 int newhurt = d1 + damage[newx][newy] + damage2[newx][newy] -  add, newcost = d2 + 2;
                 if ( newhurt < mincost[newx][newy][0] || !(mincost[newx][newy][0] ^ -1) )
                  {
                       mincost[newx][newy][0] = newhurt;
                       mincost[newx][newy][1] = newcost;
                       q.push(qst(newx,newy,newhurt,newcost));
                  }
                 else if( !(newhurt ^ mincost[newx][newy][0]) && newcost < mincost[newx][newy][1])
                  {
                        mincost[newx][newy][1] = newcost;
                        q.push(qst(newx,newy,newhurt,newcost));
                  }
             }
       }
    }
    
    
    int main(int argc,char *argv[])
    {
      //local;
      memset(damage , 0 , sizeof(damage));
      memset(damage2 , 0 , sizeof(damage2));
      memset(used,0,sizeof(used));
      scanf("%d%d%d%d%d%d",&n,&m,&sr,&sc,&tr,&tc);
      loop(i , 1 , n + 1)
       scanf("%s",s[i] + 1); 
      loop(i , 1 , n + 1)
       loop(j , 1 , m + 1)
        {
            if (s[i][j] == '#')
             ban[i][j] = 1;
            else if (s[i][j] <= 'z' && s[i][j] >= 'a')
             damage[i][j] = s[i][j] - 'a' + 1;
            else if(s[i][j] <= 'Z' && s[i][j] >= 'A')
             {
                 ban[i][j] = 1;
                 loop(k , 0 , 4)
                  damage2[i + dir[k][0]][j + dir[k][1]] += s[i][j] - 'A' + 1;
                 loop(kx , 0 , 4)
                  {
                      int newx = i + dir[kx][0] ;
                     int newy = j + dir[kx][1] ;
                     if (!inmap(newx,newy) || s[newx][newy] == '#') continue;
                     pos p1(newx,newy);
                     loop(k2 , 0 , 4)
                      {
                         int tx = i + dir[k2][0];
                         int ty = j + dir[k2][1];
                         if ( !inmap(tx,ty) || s[tx][ty] == '#' || (tx ==newx && ty == newy)) continue;
                         pos p2(tx,ty);
                         spj ju = make_pair(p1,p2);
                         if (!sb.count(ju))
                          {
                              int co = GetSameDamage(newx,newy,tx,ty);
                              E[newx][newy].pb(Edge(tx,ty,co));
                              sb.insert(ju);
                          }
                         
                      }    
                 }
             }
        }
      dijkstra();
      printf("%d %d
    ",mincost[tr][tc][0],mincost[tr][tc][1]);
      return 0;
    }
  • 相关阅读:
    TurtleBot3 Waffle (tx2版华夫)(5)激活你的雷达
    TurtleBot3 Waffle (tx2版华夫)(4)笔记本与TX2的通信
    TurtleBot3 Waffle (tx2版华夫)(3)opencr系统安装
    TurtleBot3 Waffle (tx2版华夫)(2)系统安装
    TurtleBot3 Waffle (tx2版华夫)(1)笔记本上安装虚拟机、 Ubuntu 系统
    第十九章节 BJROBOT 安卓手机 APP 导航【ROS全开源阿克曼转向智能网联无人驾驶车】
    Delphi XE2 之 FireMonkey 入门(10)
    Delphi XE2 之 FireMonkey 入门(9)
    Delphi XE2 之 FireMonkey 入门(8)
    Delphi XE2 之 FireMonkey 入门(7)
  • 原文地址:https://www.cnblogs.com/Xiper/p/4582959.html
Copyright © 2011-2022 走看看