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;
    }
  • 相关阅读:
    我该不该学习C语言
    Java入门系列-27-反射
    Java入门系列-26-JDBC
    Java入门系列-25-NIO(实现非阻塞网络通信)
    Java入门系列-24-实现网络通信
    Java入门系列-23-NIO(使用缓冲区和通道对文件操作)
    Java入门系列-22-IO流
    Java入门系列-21-多线程
    Java入门系列-20-异常
    Java入门系列-19-泛型集合
  • 原文地址:https://www.cnblogs.com/Xiper/p/4582959.html
Copyright © 2011-2022 走看看