sicily 1215 脫離地牢

Description

在一個神祕的國度裏,年輕的王子Paris與美麗的公主Helen在一塊兒過着幸福的生活。他們都隨身帶有一塊帶磁性的陰陽魔法石,身居地獄的魔王Satan早就想獲得這兩塊石頭了,只要把它們熔化,Satan就能吸取其精華大增本身的魔力。因而有一天他趁二人不留意,把他們帶到了本身的地牢,分別困在了不一樣的地方。而後Satan念起了咒語,準備煉獄,界時二人都將葬身於這地牢裏。 ios

危險!Paris與Helen都知道了Satan的意圖,他們要怎樣才能戰勝魔王,脫離地牢呢?Paris想起了父王臨終前留給他的備忘本,原來他早已料到了Satan的野心,他告訴Paris只要把兩塊魔法石合在一塊兒,念出咒語,它們便會放出無限的光亮,殺死魔王,脫離地牢,並且本子上還附下了地牢的地圖,Paris從中瞭解到了Helen的位置所在。因而他決定首先要找到Helen,可是他發現這個地牢很奇怪,它會加強二人魔法石所帶磁力的大小,並且會改變磁力的方向。這就是說,每當Pairs向南走一步,Helen有可能會被石頭吸引向北走一步。而這個地獄佈滿了岩石與熔漿,Pairs必須十分當心,不只他不能走到岩石或熔漿上,並且因爲他行走一步,Helen的位置也會改變,若是Helen碰到岩石上,那麼她將停留在原地,但若是Helen移動到了熔漿上,那麼她將死去,Paris就找不到她了。 數組

Pairs仔細分析了地圖,他找出了一條最快的行走方案,最終與Helen相聚。他們一塊兒念出了咒語"@^&#……%@%&$",轟隆一聲,地牢塌陷了,他們又重見光明…… this

Input

輸入數據第一行爲兩個整數n,m(3<=n,m<=20),表示地牢的大小,n行m列。接下來n行,每行m個字符,描述了地牢的地圖,"."表明通路,"#"表明岩石,"!"表明熔漿。輸入保證地牢是封閉的,即四周均是均是岩石或熔漿。接下來一行有四個字符"N"(北),"S"(南),"W"(西),"E"(東)的排列,表示Paris分別向NSWE四個方向走時Helen受磁石磁力影響的移動方向。

Output

輸出文件只有一行,若是Paris能找到Helen,輸出一整數d,爲Paris最少須要行走的步數;若是Paris在255步以後仍找不到Helen,則輸出"Impossible"。注意相遇是指Paris與Helen最終到達同一個格子,或者二人在相鄰兩格移動後碰在了一塊兒,然後者的步數算他們移動後的步數。

Sample Input

5 5
#####
#H..#
#.!.#
#.#P#
#####
WNSE

Sample Output

5

解釋:Paris行走方案爲NNWWS,每步事後Helen位置在(2,2), (2,2), (3,2), (4,2), (3,2)。

分析:

本題是經典的迷宮問題,可是很特殊的是本題中有兩個同時移動元素,而解決迷宮問題的廣搜方法須要記錄的是每一步的狀態,因此本題的重點實際上是在狀態的明確上。本題看似能夠用Paris一我的的狀態來記錄,可是其實會產生問題,若是Paris不訪問他已經訪問的點,會丟失部分狀態,由於他訪問同一個點並不表明Helen也會走一樣的路線。因此,狀態應該以兩人的位置組合爲標誌,同時要注意狀態的處理和判斷,那麼幾點是否訪問的記錄數組應該是思惟的。另外,注意兩人可能相撞的狀況只當兩人相鄰,而且各自走到對方的上一步節點纔可能。 spa

代碼:

// Problem#: 1215
// Submission#: 1854023
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;

#define MAX 20
int n, m;
 
struct state{
    int P_x, P_y, H_x, H_y;
    int step;
    bool same(){
        return P_x == H_x && P_y == H_y;
    }
    bool judge(){
        return P_x > 0 && P_x <= n &&  P_y > 0 && P_y <= m
        && H_x > 0 && H_x <= n && H_y > 0 && H_y <= m ;
    }
    bool ismeet(state s){
        return P_x == s.H_x && P_y == s.H_y && H_x == s.P_x && H_y == s.P_y;
    }
    state(int P_x, int P_y, int H_x, int H_y) {
        this->H_x = H_x; this->H_y = H_y; this->P_x = P_x; this->P_y = P_y; step = 0;
    }
    state() {
        step = 0;
    }
};
 
enum direction{N, S, W, E};
 
int move[4][2] = {{-1, 0},{1, 0}, {0, -1}, {0, 1}};
int match[4];
char _mape[MAX][MAX];
bool visit[MAX][MAX][MAX][MAX];
 
int P_x, P_y, H_x, H_y;
 
void bfs();
 
int main(){
    char c;
    while (cin >> n >> m){
        memset(visit, false, sizeof(visit));
 
        for (int i = 1; i <= n; i++) 
            for (int j = 1; j <= m; j++){
                cin >> _mape[i][j];
                if (_mape[i][j] == 'P'){
                    P_x = i;
                    P_y = j;
                    _mape[i][j] = '.';
                }
                if (_mape[i][j] == 'H'){
                    H_x = i;
                    H_y = j;
                    _mape[i][j] = '.';
                }
            }
 
            for (int i = 0; i < 4; i++){
                cin >> c;
                switch (c){
                case 'N':
                    match[i] = N;
                    break;
                case 'S':
                    match[i] = S;
                    break;
                case 'W':
                    match[i] = W;
                    break;
                case 'E':
                    match[i] = E;
                    break;
                }
            }
            bfs();
    }
    return 0;
}
 
void bfs(){
    queue <state> buffer;
    buffer.push(state(P_x, P_y, H_x, H_y));
 
    state temp, next;
 
    while (!buffer.empty()){
        temp = buffer.front();
        buffer.pop();
        if (temp.step > 255){
            cout << "Impossible" << endl;
            return;
        }
        for (int i = 0; i < 4; i++){
            next.P_x = temp.P_x + move[i][0];
            next.P_y = temp.P_y + move[i][1];
            next.H_x = temp.H_x + move[match[i]][0];
            next.H_y = temp.H_y + move[match[i]][1];
            next.step = temp.step + 1;
         
            if (next.judge() && _mape[next.H_x][next.H_y] != '!' 
        && _mape[next.P_x][next.P_y] == '.' ){
                if (_mape[next.H_x][next.H_y] == '#'){
                    next.H_x -= move[match[i]][0];
                    next.H_y -= move[match[i]][1];
                }
                if (!visit[next.P_x][next.P_y][next.H_x][next.H_y]){
                    visit[next.P_x][next.P_y][next.H_x][next.H_y] = true;
                    if (next.same() || temp.ismeet(next)){
                        cout << next.step << endl;
                        return ;
                    }
                    else
                        buffer.push(next);
                }
            }
        }
 
    }
    cout << "Impossible" << endl;
}
相關文章
相關標籤/搜索