解题技巧: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; }
时间: 2024-10-06 04:25:41