标签:
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.
The first line contains two integers N and M (1≤N,M≤500).
The second line contains 4 integers SR,SC,TR,TC (1≤SR,TR≤N and 1≤SC,TC≤M).
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 the lowest total damage and the lowest steps in all safest path.
Sample Input | Sample Output |
---|---|
3 5 1 1 3 5 ..b.. .zC#. ..a.. |
4 6 |
#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\n",mincost[tr][tc][0],mincost[tr][tc][1]); return 0; }
标签:
原文地址:http://www.cnblogs.com/Xiper/p/4582959.html