zoukankan      html  css  js  c++  java
  • 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
    ", mp.step);
        } else {
            printf("%s
    ", "Impossible");
        }
        return 0;
    }
    

      

  • 相关阅读:
    Ajax基本案例详解之$.getjson的实现
    Ajax基本案例详解之$.getjson的实现
    Ajax传递json数据
    Ajax传递json数据
    Ajax基本案例详解之load的实现
    多节点日志数据 数据集成
    crontab 问题分析
    不留文档的某某离开后 审计服务器操作历史
    /cloudmonitor.log 主机监控
    网关会对开发者的接口非业务调用错误做统一处理
  • 原文地址:https://www.cnblogs.com/mchcylh/p/5104945.html
Copyright © 2011-2022 走看看