1215. 脱离地牢

解题技巧:1.广度优先搜索

     2.分离地图和人物位置状态

     3.压缩人物位置状态为一个整数,以便去掉重复的状态

#include <cstdio>
#include <set>
#include <map>
#include <queue>
using namespace std;

struct Cor {
    int r, c;
    Cor(int r_ = 0, int c_ = 0) : r(r_), c(c_) {}
    Cor operator+(const Cor &cor) {
        return Cor(r + cor.r, c + cor.c);
    }
    Cor& operator=(const Cor &cor) {
        r = cor.r;
        c = cor.c;
        return *this;
    }
    bool operator==(const Cor&cor) {
        return r == cor.r && c == cor.c;
    }
};

struct State {
    Cor h, p;
    State() {}
};

struct Map {
    static const int maxr = 20;
    static const int maxc = 20;
    static const int maxd = 4;

    static const int HR = 1;
    static const int HC = 100;
    static const int PR = 10000;
    static const int PC = 1000000;

    static const int max_step = 255;

    char m[maxr][maxc+1];
    char p_d[maxd + 1];
    char h_d[maxd + 1];
    int rows, cols;

    queue<State> state_queue;

    map<char, Cor> d_x;
    set<int> ids;

    bool success;
    int step;

    void init() {
        d_x.insert(make_pair('N', Cor(-1, 0)));
        d_x.insert(make_pair('S', Cor(1, 0)));
        d_x.insert(make_pair('W', Cor(0, -1)));
        d_x.insert(make_pair('E', Cor(0, 1)));
        p_d[0] = 'N'; p_d[1] = 'S'; p_d[2] = 'W'; p_d[3] = 'E';
        while (!state_queue.empty()) state_queue.pop();
    }

    void input() {
        scanf("%d%d", &rows, &cols);
        for (int r = 0; r < rows; ++r)
            scanf("%s", m[r]);
        scanf("%s", h_d);
    }

    int makeId(const State & state) {
        return state.h.r * HR + state.h.c * HC + state.p.r * PR + state.p.c * PC;
    }

    void extractHP() {
        State state;
        for (int r = 0; r < rows; ++r) {
            for (int c = 0; c < cols; ++c) {
                if (m[r][c] == 'H') {
                    state.h.r = r;
                    state.h.c = c;
                    m[r][c] = '.';
                } else if (m[r][c] == 'P') {
                    state.p.r = r;
                    state.p.c = c;
                    m[r][c] = '.';
                }
            }
        }
        int id = makeId(state);
        ids.insert(id);
        state_queue.push(state);
    }

    void solve() {
        success = false;
        step = 0;
        while (!state_queue.empty() && step < max_step && !success) {
            ++step;
            int size = state_queue.size();
            while (size-- && !success) {
                State &state = state_queue.front();
                
                for (int i = 0; i < maxd; ++i) {
                    Cor & p_d_cor = d_x[p_d[i]];
                    Cor & h_d_cor = d_x[h_d[i]];
                    State next_state;
                    next_state.h = state.h + h_d_cor;
                    if (m[next_state.h.r][next_state.h.c] == '#') {
                        next_state.h = state.h;
                    } else if (m[next_state.h.r][next_state.h.c] == '!') {
                        continue;
                    }
                    next_state.p = state.p + p_d_cor;
                    if (m[next_state.p.r][next_state.p.c] == '#') {
                        continue;
                    } else if (m[next_state.p.r][next_state.p.c] == '!') {
                        continue;
                    }
                    if ((next_state.h == next_state.p) || (next_state.h == state.p && next_state.p == state.h)) {
                        // 达到目的地
                        success = true;
                        break;
                    }
                    int id = makeId(next_state);
                    if (ids.find(id) == ids.end()) {
                        ids.insert(id);
                        state_queue.push(next_state);
                    }
                }

                state_queue.pop();
            }
        }
    }

};

int main() {
    Map mp;
    mp.init();
    mp.input();
    mp.extractHP();
    mp.solve();
    if (mp.success) {
        printf("%d\n", mp.step);
    } else {
        printf("%s\n", "Impossible");
    }
    return 0;
}

  

posted @ 2016-01-06 11:34  MchCyLh  阅读(294)  评论(0编辑  收藏  举报