2013-05-21 19:46:02Morris

[UVA][spfa] 10967 - The Great Escape

Problem D

The Great Escape

PoorKianoosh! 6 weeks since he was officially accepted as a citizen of Barareh andduring this time he has had nothing but Nochophskew for his breakfast, lunchand dinner. And nowadays, during the nights, he dreams of nothing but a smallpiece of bread, some cheese and a glass of milk to have for his breakfast. Andduring the days, he thinks of nothing but a great escape from this weird cityin order to turn his night-time dreams into reality.

 

Aftercarefully checking all the potential ways out of the city, he concluded thatthere are only three such possible ways. The first one is through the city gatewhich is of course guarded by fully-armed guards, ready to kill any creaturetrying to go through the gate without permission. The second way is passingthrough the northern walls of the city and going through a jungle whichcontains nothing but those deadly snakes called NeshimanGazes (And be sure thatKianoosh does not like to repeat his creepy experience with them again).

 

Finally,the third and the last (and of course the only feasible) way is passing througha secret door in the famous so called HezarDaroon Castle(means a castle with thousands of doors). Unfortunately, the problem with thiscastle is that no one actually knows the way to reach this secret door.

 

Afterspending some time gathering information about the castle, Kianoosh found outthat HezarDaroon can actually be modeled as an  grid with each cellrepresenting a room in the castle. There is always a door between twoneighboring rooms but there are some rooms which contain a NeshimanGaz ready toserve anyone trying to enter the room with its poisonous bites.

 

Thereare also some rooms which contain a rotating door. A rotating door is actually acylinder positioned at the center of the room with a slice removed from it. InFigure 1, you can see a room with a rotating door with its removed slice facingtowards west.

 

 

 

Figure 1. A Rotating Door

 

Asit can be seen, one can only enter the room from the neighbor to which theremoved slice is facing. And once Kianoosh enters the room, he can rotate thedoor clockwise or counter-clockwise in order to reach the other doors in theroom. For example, in the configuration of figure 1, if he rotates the doorclockwise by 90 degrees, he can reach the door to the north and if he continuesrotating the door by another 90 degrees in the same direction, he can reach thedoor to east.

 

Anotherimportant fact about the rotating doors is that associated to each door is anumber  which is the amount oftime, measured in seconds, that it takes for a normal human-being(likeKianoosh) to rotate the door by 90 degrees. You may also assume that going froma room to its neighbor room takes exactly 1 second.

 

Today,after spending a noticeable amount of money, Kianoosh managed to buy a map ofthe castle from underground shops of Barareh. Taking a look at the map, hefound that the entrance to the castle is located at the lower-left corner andthe secret door is located at the upper-right corner of the grid. He can alsosee the position and the initial configuration of the rotating doors and thecoordinates of rooms containing the deadly NeshimanGazes to which Kianoosh doesnot like to enter.

 

Kianooshis happy. He is only one step away from his dreams coming true. But how can hefind his way to the secret door? Yes! He needs help! And as a geniusproblem-solver, you should help him find the path with the minimum requiredtime to reach the secret passage from the lower-left corner of the castle.

 

The Input

Thefirst line of the input contains an integer  which is the number oftest cases. Each test case begins with a line containing (the number of rows) and (the number of columns) followed by  lines, with the th line containing  characters, the th character of which representing the status of the th cell in the th row of the grid (counted from north). Each character mayhave six different values. A ‘.’ character represents anormal room while a ‘#’ represents a room containing a NeshimanGaz and ‘N’, ‘W’, ‘E’, ‘S’ represent a room with arotating door facing north, west, east, and south respectively. The map isfollowed by  integers, the th of which is equal to  for the th door, counting the doors from the north-west corner in arow major order. You can assume that (which is the number of rotating doors in the castle) is nomore than 500, and the entrance (room at lower-left corner) and the roomcontaining the secret door (room at upper-right corner) does not containNeshimanGazes or rotating doors.

 

The Output

Foreach test case, your program should output a line containing a single integerwhich is the minimum amount of time required for Kianoosh to reach the secretdoor. In the case the secret door is not reachable with respect to the givenmap and rules, a line containing the phrase “Poor Kianoosh” should be printed.

 

Sample Input

1

3 3
.#.
..W
...
10

 

Sample Output

14

 


Amirkabir University of Technology - Local Contest - Round #2

題目描述:

要求從左下角到右上角,中間會經過旋轉門,而旋轉門的房間固定只有一個房間能進入。
旋轉門每轉90度,會消耗時間 d,然而每個旋轉門所消耗的時間都不同。
而一般進入房間消耗單位 1 時間,求最少時間。

題目解法:

要特別考慮旋轉門接著旋轉門走,為了方便起見,使用記錄上一個方向的進入。
因此每個點都會有四個方向的記錄,從來哪個方位的最短路徑。

#include <stdio.h>
#include <queue>
using namespace std;
char g[105][105];
int dis[105][105][4], inq[105][105][4]; //[pointX][pointY][prevDir]
int n, m, d[105][105];
int dx[] = {1,0,0,-1};// to N, E, W, S
int dy[] = {0,-1,1,0};
void spfa() {
    int i, j, k, x, y, r, tx, ty, rx, ry;
    int cost;
    for(i = 0; i < n; i++)
        for(j = 0; j < m; j++)
            for(k = 0; k < 4; k++)
                dis[i][j][k] = 0xfffffff, inq[i][j][k] = 0;
    queue<int> X, Y, R;
    X.push(n-1), Y.push(0), R.push(0);
    dis[n-1][0][0] = 0;
    while(!X.empty()) {
        x = X.front(), X.pop();
        y = Y.front(), Y.pop();
        r = R.front(), R.pop();
        inq[x][y][r] = 0;
        if(g[x][y] == '.') {
            for(i = 0; i < 4; i++) {
                tx = x+dx[i], ty = y+dy[i];
                if(tx < 0 || ty < 0 || tx >= n || ty >= m)
                    continue;
                if(g[tx][ty] == '#')    continue;
                bool updateFlag = false;
                if(g[tx][ty] == '.')
                    updateFlag = true;
                if(g[tx][ty] == 'N' && i == 0)
                    updateFlag = true;
                if(g[tx][ty] == 'E' && i == 1)
                    updateFlag = true;
                if(g[tx][ty] == 'W' && i == 2)
                    updateFlag = true;
                if(g[tx][ty] == 'S' && i == 3)
                    updateFlag = true;
                if(updateFlag == true) {
                    if(dis[tx][ty][i] > dis[x][y][r]+1) {
                        dis[tx][ty][i] = dis[x][y][r]+1;
                        if(inq[tx][ty][i] == 0) {
                            inq[tx][ty][i] = 1;
                            X.push(tx), Y.push(ty), R.push(i);
                        }
                    }
                }
            }
        } else {// rotate door
            for(i = 0; i < 4; i++) {
                tx = x+dx[i], ty = y+dy[i];
                if(tx < 0 || ty < 0 || tx >= n || ty >= m)
                    continue;
                if(g[tx][ty] == '#')    continue;
                if(i+r == 3 || i == r)
                    cost = 2*d[x][y];
                else
                    cost = d[x][y];
                bool updateFlag = false;
                if(g[tx][ty] == '.')
                    updateFlag = true;
                if(g[tx][ty] == 'N' && i == 0)
                    updateFlag = true;
                if(g[tx][ty] == 'E' && i == 1)
                    updateFlag = true;
                if(g[tx][ty] == 'W' && i == 2)
                    updateFlag = true;
                if(g[tx][ty] == 'S' && i == 3)
                    updateFlag = true;
                if(updateFlag == true) {
                    if(dis[tx][ty][i] > dis[x][y][r]+1+cost) {
                        dis[tx][ty][i] = dis[x][y][r]+1+cost;
                        if(inq[tx][ty][i] == 0) {
                            inq[tx][ty][i] = 1;
                            X.push(tx), Y.push(ty), R.push(i);
                        }
                    }
                }
            }
        }
    }
    int ret = dis[0][m-1][0];
    for(i = 0; i < 4; i++)
        ret = min(ret, dis[0][m-1][i]);
    if(ret == 0xfffffff)
        puts("Poor Kianoosh");
    else
        printf("%d\n", ret);
}
int main() {
    int test, i, j;
    scanf("%d", &test);
    while(test--) {
        scanf("%d %d", &n, &m);
        while(getchar() != '\n');
        for(i = 0; i < n; i++)
            gets(g[i]);
        for(i = 0; i < n; i++) {
            for(j = 0; j < m; j++) {
                if(g[i][j] != '.' && g[i][j] !='#')
                    scanf("%d", &d[i][j]);
            }
        }
        spfa();
    }
    return 0;
}