记录编号 614716 评测结果 AA
题目名称 3488.[POJ 1475]推箱子 最终得分 100
用户昵称 GravatarChenBp 是否通过 通过
代码语言 C++ 运行时间 0.158 s
提交时间 2026-04-14 14:09:38 内存使用 3.39 MiB
显示代码纯文本
#include <cstring>
#include <iostream>
#include <queue>
#include <utility>
using namespace std;
const int cz[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
const char cc[4] = {'n', 's', 'w', 'e'};
char g[25][25];
struct pos {
    int x, y;
    pos(int xx = 0, int yy = 0) {
        x = xx;
        y = yy;
    }
    bool operator==(const pos& yo) const& { return x == yo.x && y == yo.y; }
    bool operator!=(const pos& yo) const& { return x != yo.x || y != yo.y; }
};
struct node {
    pos p;
    int dir;
    int pc, bc;
    string ph;
    node(int xx, int yy, int dd, int pp, int bb, string pth) {
        p.x = xx;
        p.y = yy;
        dir = dd;
        pc = pp;
        bc = bb;
        ph = pth;
    }
    node(pos xx, int dd, int pp, int bb, string pth) {
        p = xx;
        dir = dd;
        pc = pp;
        bc = bb;
        ph = pth;
    }
    bool operator<(const node& yo) const& {
        if (bc != yo.bc) return bc > yo.bc;
        return pc > yo.pc;
    }
};
bool vis[25][25];
int r, c;
bool pd(pos x) {
    if (x.x >= 1 && x.y >= 1 && x.x <= r && x.y <= c && g[x.x][x.y] != '#') return 1;
    return 0;
}
/**
 *  @brief  查找人从 s 到 e 的最短方案, b 是箱子的初始位置.
 *  @param  s  人初始位置
 *  @param e 人目的位置
 *  @param b 箱子的初始位置
 */
string pbfs(pos s, pos e, pos b) {
    if (s == e) return "";
    memset(vis, 0, sizeof(vis));
    queue<pair<pos, string>> q;
    q.push(make_pair(s, ""));
    vis[s.x][s.y] = 1;
    while (!q.empty()) {
        pos u = q.front().first;
        string str = q.front().second;
        q.pop();
        for (int i = 0; i < 4; i++) {
            pos xx = pos(u.x + cz[i][0], u.y + cz[i][1]);
            if (pd(xx) && xx != b && !vis[xx.x][xx.y]) {
                q.push(make_pair(xx, str + cc[i]));
                vis[xx.x][xx.y] = 1;
                if (xx == e) return str + cc[i];
            }
        }
    }
    return "-1";
}
pair<int, int> dis[25][25][4];
/**
 *  @brief  查找箱子从 s 到 e 的最短方案, po 是人的初始位置.
 *  @param  s  箱子初始位置
 *  @param e 箱子目的位置
 *  @param po 人的初始位置
 */
string bbfs(pos s, pos e, pos po) {
    memset(dis, 0x3f, sizeof(dis));
    priority_queue<node> q;
    for (int i = 0; i < 4; i++) {
        pos xx = s;
        xx.x += cz[i][0];
        xx.y += cz[i][1];
        pos yy = s;
        yy.x -= cz[i][0];
        yy.y -= cz[i][1];
        string str = pbfs(po, yy, s);
        if (pd(xx) && pd(yy) && str != "-1") {
            q.push(node(xx, i, str.size(), 1, str + char(cc[i] - 32)));
            dis[xx.x][xx.y][i] = make_pair(1, str.size());
        }
    }
    while (!q.empty()) {
        node u = q.top();
        q.pop();
        if (make_pair(u.bc, u.pc) > dis[u.p.x][u.p.y][u.dir]) continue;
        if (u.p == e) return u.ph;
        pos po = u.p;
        po.x -= cz[u.dir][0];
        po.y -= cz[u.dir][1];
        for (int i = 0; i < 4; i++) {
            pos xx = u.p, yy = u.p;
            xx.x += cz[i][0];
            xx.y += cz[i][1];
            yy.x -= cz[i][0];
            yy.y -= cz[i][1];
            string str = pbfs(po, yy, u.p);
            if (pd(xx) && pd(yy) && str != "-1" &&
                make_pair(u.bc + 1, u.pc + (int)str.size()) < dis[xx.x][xx.y][i]) {
                q.push(node(xx, i, u.pc + str.size(), u.bc + 1, u.ph + str + char(cc[i] - 32)));
                dis[xx.x][xx.y][i] = make_pair(u.bc + 1, u.pc + str.size());
            }
        }
    }
    return "Impossible.";
}
int main() {
    int t = 0;
    while (true) {
        t++;
        cin >> r >> c;
        if (!(r && c)) return 0;
        pos s, e, b;
        for (int i = 1; i <= r; i++) {
            for (int j = 1; j <= c; j++) {
                cin >> g[i][j];
                if (g[i][j] == 'B') {
                    b = pos(i, j);
                    g[i][j] = '.';
                }
                if (g[i][j] == 'S') {
                    s = pos(i, j);
                    g[i][j] = '.';
                }
                if (g[i][j] == 'T') {
                    e = pos(i, j);
                    g[i][j] = '.';
                }
            }
        }
        cout << "Maze #" << t << "\n" << bbfs(b, e, s) << endl << endl;
    }
}