#include <bits/stdc++.h>
using namespace std;
struct Pos {
int r, c;
bool operator==(const Pos &o) const { return r == o.r && c == o.c; }
bool operator!=(const Pos &o) const { return !(*this == o); }
};
struct State {
Pos player, box;
int g, h;
bool operator>(const State &o) const { return g + h > o.g + o.h; }
};
struct HashState {
size_t operator()(const pair<Pos, Pos> &p) const {
return (p.first.r * 31 + p.first.c) * 131 + (p.second.r * 31 + p.second.c);
}
};
int R = 16, C = 16;
vector<string> grid;
Pos myPos, goalA, goalB;
vector<vector<bool>> isDeadCorner;
int dr[4] = {-1, 1, 0, 0};
int dc[4] = {0, 0, -1, 1};
char moveChar[4] = {'U', 'D', 'L', 'R'};
bool inBounds(int r, int c) {
return r >= 0 && r < R && c >= 0 && c < C;
}
}bool isWall(int r,int c){
// be careful !!!!! if we can go into grid with 'b'
if (grid[r][c] == 'b') return false;
return !inb(r,c) || grid[r][c]=='#';
}
int manhattan(const Pos &a, const Pos &b) {
return abs(a.r - b.r) + abs(a.c - b.c);
}
// Dead corner precompute
void computeDeadCorners() {
isDeadCorner.assign(R, vector<bool>(C, false));
for (int r = 0; r < R; r++) {
for (int c = 0; c < C; c++) {
if (grid[r][c] == '#' || Pos{r,c} == goalA) continue;
bool up = isWall(r - 1, c), down = isWall(r + 1, c);
bool left = isWall(r, c - 1), right = isWall(r, c + 1);
if ((up && left) || (up && right) || (down && left) || (down && right)) {
isDeadCorner[r][c] = true;
}
}
}
}
// BFS to see if player can reach targetPos without moving box
bool canReach(Pos start, Pos target, Pos box) {
queue<Pos> q;
vector<vector<bool>> vis(R, vector<bool>(C, false));
q.push(start);
vis[start.r][start.c] = true;
while (!q.empty()) {
Pos cur = q.front(); q.pop();
if (cur == target) return true;
for (int k = 0; k < 4; k++) {
int nr = cur.r + dr[k], nc = cur.c + dc[k];
if (!inBounds(nr, nc) || vis[nr][nc] || grid[nr][nc] == '#') continue;
if (nr == box.r && nc == box.c) continue;
vis[nr][nc] = true;
q.push({nr, nc});
}
}
return false;
}
// A* search: returns path string or ""
string aStarBox(Pos startPlayer, Pos startBox) {
priority_queue<State, vector<State>, greater<State>> pq;
unordered_map<pair<Pos, Pos>, pair<Pos, Pos>, HashState> parent;
unordered_map<pair<Pos, Pos>, char, HashState> moveTaken;
unordered_set<pair<Pos, Pos>, HashState> visited;
auto heuristic = [&](const Pos &box) {
return manhattan(box, goalA) * 3;
};
pq.push({startPlayer, startBox, 0, heuristic(startBox)});
visited.insert({startPlayer, startBox});
while (!pq.empty()) {
State cur = pq.top(); pq.pop();
if (cur.box == goalA) {
// reconstruct
string path;
pair<Pos, Pos> key = {cur.player, cur.box};
while (parent.count(key)) {
path.push_back(moveTaken[key]);
key = parent[key];
}
reverse(path.begin(), path.end());
return path;
}
for (int k = 0; k < 4; k++) {
Pos newPlayer = {cur.player.r + dr[k], cur.player.c + dc[k]};
if (!inBounds(newPlayer.r, newPlayer.c) || grid[newPlayer.r][newPlayer.c] == '#') continue;
// push box
if (newPlayer == cur.box) {
Pos newBox = {cur.box.r + dr[k], cur.box.c + dc[k]};
if (isWall(newBox.r, newBox.c) || (isDeadCorner[newBox.r][newBox.c] && newBox != goalA) || newBox == goalB)
continue;
if (visited.count({newPlayer, newBox})) continue;
visited.insert({newPlayer, newBox});
pq.push({newPlayer, newBox, cur.g + 1, heuristic(newBox)});
parent[{newPlayer, newBox}] = {cur.player, cur.box};
moveTaken[{newPlayer, newBox}] = moveChar[k];
}
// walk
else {
if (visited.count({newPlayer, cur.box})) continue;
visited.insert({newPlayer, cur.box});
pq.push({newPlayer, cur.box, cur.g + 1, heuristic(cur.box)});
parent[{newPlayer, cur.box}] = {cur.player, cur.box};
moveTaken[{newPlayer, cur.box}] = moveChar[k];
}
}
}
return "";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
grid.resize(R);
for (int i = 0; i < R; i++) {
cin >> grid[i];
for (int j = 0; j < C; j++) {
if (grid[i][j] == 'a') myPos = {i, j};
if (grid[i][j] == 'A') goalA = {i, j};
if (grid[i][j] == 'B') goalB = {i, j};
}
}
computeDeadCorners();
vector<Pos> boxes;
for (int r = 0; r < R; r++)
for (int c = 0; c < C; c++)
if (grid[r][c] == 'X') boxes.push_back({r, c});
string bestPath;
int bestDist = 1e9;
for (auto &box : boxes) {
if (isDeadCorner[box.r][box.c] && box != goalA) continue;
int distToBox = manhattan(myPos, box);
if (distToBox > 20) continue; // filter far boxes
string path = aStarBox(myPos, box);
if (!path.empty() && distToBox < bestDist) {
bestDist = distToBox;
bestPath = path;
}
}
if (!bestPath.empty())
cout << bestPath[0] << "\n";
else {
// random move fallback
vector<int> dirs = {0, 1, 2, 3};
random_shuffle(dirs.begin(), dirs.end());
for (int k : dirs) {
int nr = myPos.r + dr[k], nc = myPos.c + dc[k];
if (!isWall(nr, nc)) {
cout << moveChar[k] << "\n";
return 0;
}
}
cout << "U\n"; // default
}
return 0;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgpzdHJ1Y3QgUG9zIHsKICAgIGludCByLCBjOwogICAgYm9vbCBvcGVyYXRvcj09KGNvbnN0IFBvcyAmbykgY29uc3QgeyByZXR1cm4gciA9PSBvLnIgJiYgYyA9PSBvLmM7IH0KICAgIGJvb2wgb3BlcmF0b3IhPShjb25zdCBQb3MgJm8pIGNvbnN0IHsgcmV0dXJuICEoKnRoaXMgPT0gbyk7IH0KfTsKCnN0cnVjdCBTdGF0ZSB7CiAgICBQb3MgcGxheWVyLCBib3g7CiAgICBpbnQgZywgaDsKICAgIGJvb2wgb3BlcmF0b3I+KGNvbnN0IFN0YXRlICZvKSBjb25zdCB7IHJldHVybiBnICsgaCA+IG8uZyArIG8uaDsgfQp9OwoKc3RydWN0IEhhc2hTdGF0ZSB7CiAgICBzaXplX3Qgb3BlcmF0b3IoKShjb25zdCBwYWlyPFBvcywgUG9zPiAmcCkgY29uc3QgewogICAgICAgIHJldHVybiAocC5maXJzdC5yICogMzEgKyBwLmZpcnN0LmMpICogMTMxICsgKHAuc2Vjb25kLnIgKiAzMSArIHAuc2Vjb25kLmMpOwogICAgfQp9OwoKaW50IFIgPSAxNiwgQyA9IDE2Owp2ZWN0b3I8c3RyaW5nPiBncmlkOwpQb3MgbXlQb3MsIGdvYWxBLCBnb2FsQjsKdmVjdG9yPHZlY3Rvcjxib29sPj4gaXNEZWFkQ29ybmVyOwoKaW50IGRyWzRdID0gey0xLCAxLCAwLCAwfTsKaW50IGRjWzRdID0gezAsIDAsIC0xLCAxfTsKY2hhciBtb3ZlQ2hhcls0XSA9IHsnVScsICdEJywgJ0wnLCAnUid9OwoKYm9vbCBpbkJvdW5kcyhpbnQgciwgaW50IGMpIHsKICAgIHJldHVybiByID49IDAgJiYgciA8IFIgJiYgYyA+PSAwICYmIGMgPCBDOwp9Cgp9Ym9vbCBpc1dhbGwoaW50IHIsaW50IGMpeyAKCS8vIGJlIGNhcmVmdWwgISEhISEgaWYgd2UgY2FuIGdvIGludG8gZ3JpZCB3aXRoICdiJwoJaWYgKGdyaWRbcl1bY10gPT0gJ2InKSByZXR1cm4gZmFsc2U7CglyZXR1cm4gIWluYihyLGMpIHx8IGdyaWRbcl1bY109PScjJzsgCn0KCmludCBtYW5oYXR0YW4oY29uc3QgUG9zICZhLCBjb25zdCBQb3MgJmIpIHsKICAgIHJldHVybiBhYnMoYS5yIC0gYi5yKSArIGFicyhhLmMgLSBiLmMpOwp9CgovLyBEZWFkIGNvcm5lciBwcmVjb21wdXRlCnZvaWQgY29tcHV0ZURlYWRDb3JuZXJzKCkgewogICAgaXNEZWFkQ29ybmVyLmFzc2lnbihSLCB2ZWN0b3I8Ym9vbD4oQywgZmFsc2UpKTsKICAgIGZvciAoaW50IHIgPSAwOyByIDwgUjsgcisrKSB7CiAgICAgICAgZm9yIChpbnQgYyA9IDA7IGMgPCBDOyBjKyspIHsKICAgICAgICAgICAgaWYgKGdyaWRbcl1bY10gPT0gJyMnIHx8IFBvc3tyLGN9ID09IGdvYWxBKSBjb250aW51ZTsKICAgICAgICAgICAgYm9vbCB1cCA9IGlzV2FsbChyIC0gMSwgYyksIGRvd24gPSBpc1dhbGwociArIDEsIGMpOwogICAgICAgICAgICBib29sIGxlZnQgPSBpc1dhbGwociwgYyAtIDEpLCByaWdodCA9IGlzV2FsbChyLCBjICsgMSk7CiAgICAgICAgICAgIGlmICgodXAgJiYgbGVmdCkgfHwgKHVwICYmIHJpZ2h0KSB8fCAoZG93biAmJiBsZWZ0KSB8fCAoZG93biAmJiByaWdodCkpIHsKICAgICAgICAgICAgICAgIGlzRGVhZENvcm5lcltyXVtjXSA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KCi8vIEJGUyB0byBzZWUgaWYgcGxheWVyIGNhbiByZWFjaCB0YXJnZXRQb3Mgd2l0aG91dCBtb3ZpbmcgYm94CmJvb2wgY2FuUmVhY2goUG9zIHN0YXJ0LCBQb3MgdGFyZ2V0LCBQb3MgYm94KSB7CiAgICBxdWV1ZTxQb3M+IHE7CiAgICB2ZWN0b3I8dmVjdG9yPGJvb2w+PiB2aXMoUiwgdmVjdG9yPGJvb2w+KEMsIGZhbHNlKSk7CiAgICBxLnB1c2goc3RhcnQpOwogICAgdmlzW3N0YXJ0LnJdW3N0YXJ0LmNdID0gdHJ1ZTsKICAgIHdoaWxlICghcS5lbXB0eSgpKSB7CiAgICAgICAgUG9zIGN1ciA9IHEuZnJvbnQoKTsgcS5wb3AoKTsKICAgICAgICBpZiAoY3VyID09IHRhcmdldCkgcmV0dXJuIHRydWU7CiAgICAgICAgZm9yIChpbnQgayA9IDA7IGsgPCA0OyBrKyspIHsKICAgICAgICAgICAgaW50IG5yID0gY3VyLnIgKyBkcltrXSwgbmMgPSBjdXIuYyArIGRjW2tdOwogICAgICAgICAgICBpZiAoIWluQm91bmRzKG5yLCBuYykgfHwgdmlzW25yXVtuY10gfHwgZ3JpZFtucl1bbmNdID09ICcjJykgY29udGludWU7CiAgICAgICAgICAgIGlmIChuciA9PSBib3guciAmJiBuYyA9PSBib3guYykgY29udGludWU7CiAgICAgICAgICAgIHZpc1tucl1bbmNdID0gdHJ1ZTsKICAgICAgICAgICAgcS5wdXNoKHtuciwgbmN9KTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gZmFsc2U7Cn0KCi8vIEEqIHNlYXJjaDogcmV0dXJucyBwYXRoIHN0cmluZyBvciAiIgpzdHJpbmcgYVN0YXJCb3goUG9zIHN0YXJ0UGxheWVyLCBQb3Mgc3RhcnRCb3gpIHsKICAgIHByaW9yaXR5X3F1ZXVlPFN0YXRlLCB2ZWN0b3I8U3RhdGU+LCBncmVhdGVyPFN0YXRlPj4gcHE7CiAgICB1bm9yZGVyZWRfbWFwPHBhaXI8UG9zLCBQb3M+LCBwYWlyPFBvcywgUG9zPiwgSGFzaFN0YXRlPiBwYXJlbnQ7CiAgICB1bm9yZGVyZWRfbWFwPHBhaXI8UG9zLCBQb3M+LCBjaGFyLCBIYXNoU3RhdGU+IG1vdmVUYWtlbjsKICAgIHVub3JkZXJlZF9zZXQ8cGFpcjxQb3MsIFBvcz4sIEhhc2hTdGF0ZT4gdmlzaXRlZDsKCiAgICBhdXRvIGhldXJpc3RpYyA9IFsmXShjb25zdCBQb3MgJmJveCkgewogICAgICAgIHJldHVybiBtYW5oYXR0YW4oYm94LCBnb2FsQSkgKiAzOwogICAgfTsKCiAgICBwcS5wdXNoKHtzdGFydFBsYXllciwgc3RhcnRCb3gsIDAsIGhldXJpc3RpYyhzdGFydEJveCl9KTsKICAgIHZpc2l0ZWQuaW5zZXJ0KHtzdGFydFBsYXllciwgc3RhcnRCb3h9KTsKCiAgICB3aGlsZSAoIXBxLmVtcHR5KCkpIHsKICAgICAgICBTdGF0ZSBjdXIgPSBwcS50b3AoKTsgcHEucG9wKCk7CiAgICAgICAgaWYgKGN1ci5ib3ggPT0gZ29hbEEpIHsKICAgICAgICAgICAgLy8gcmVjb25zdHJ1Y3QKICAgICAgICAgICAgc3RyaW5nIHBhdGg7CiAgICAgICAgICAgIHBhaXI8UG9zLCBQb3M+IGtleSA9IHtjdXIucGxheWVyLCBjdXIuYm94fTsKICAgICAgICAgICAgd2hpbGUgKHBhcmVudC5jb3VudChrZXkpKSB7CiAgICAgICAgICAgICAgICBwYXRoLnB1c2hfYmFjayhtb3ZlVGFrZW5ba2V5XSk7CiAgICAgICAgICAgICAgICBrZXkgPSBwYXJlbnRba2V5XTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXZlcnNlKHBhdGguYmVnaW4oKSwgcGF0aC5lbmQoKSk7CiAgICAgICAgICAgIHJldHVybiBwYXRoOwogICAgICAgIH0KCiAgICAgICAgZm9yIChpbnQgayA9IDA7IGsgPCA0OyBrKyspIHsKICAgICAgICAgICAgUG9zIG5ld1BsYXllciA9IHtjdXIucGxheWVyLnIgKyBkcltrXSwgY3VyLnBsYXllci5jICsgZGNba119OwogICAgICAgICAgICBpZiAoIWluQm91bmRzKG5ld1BsYXllci5yLCBuZXdQbGF5ZXIuYykgfHwgZ3JpZFtuZXdQbGF5ZXIucl1bbmV3UGxheWVyLmNdID09ICcjJykgY29udGludWU7CgogICAgICAgICAgICAvLyBwdXNoIGJveAogICAgICAgICAgICBpZiAobmV3UGxheWVyID09IGN1ci5ib3gpIHsKICAgICAgICAgICAgICAgIFBvcyBuZXdCb3ggPSB7Y3VyLmJveC5yICsgZHJba10sIGN1ci5ib3guYyArIGRjW2tdfTsKICAgICAgICAgICAgICAgIGlmIChpc1dhbGwobmV3Qm94LnIsIG5ld0JveC5jKSB8fCAoaXNEZWFkQ29ybmVyW25ld0JveC5yXVtuZXdCb3guY10gJiYgbmV3Qm94ICE9IGdvYWxBKSB8fCBuZXdCb3ggPT0gZ29hbEIpCiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICBpZiAodmlzaXRlZC5jb3VudCh7bmV3UGxheWVyLCBuZXdCb3h9KSkgY29udGludWU7CiAgICAgICAgICAgICAgICB2aXNpdGVkLmluc2VydCh7bmV3UGxheWVyLCBuZXdCb3h9KTsKICAgICAgICAgICAgICAgIHBxLnB1c2goe25ld1BsYXllciwgbmV3Qm94LCBjdXIuZyArIDEsIGhldXJpc3RpYyhuZXdCb3gpfSk7CiAgICAgICAgICAgICAgICBwYXJlbnRbe25ld1BsYXllciwgbmV3Qm94fV0gPSB7Y3VyLnBsYXllciwgY3VyLmJveH07CiAgICAgICAgICAgICAgICBtb3ZlVGFrZW5be25ld1BsYXllciwgbmV3Qm94fV0gPSBtb3ZlQ2hhcltrXTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyB3YWxrCiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgaWYgKHZpc2l0ZWQuY291bnQoe25ld1BsYXllciwgY3VyLmJveH0pKSBjb250aW51ZTsKICAgICAgICAgICAgICAgIHZpc2l0ZWQuaW5zZXJ0KHtuZXdQbGF5ZXIsIGN1ci5ib3h9KTsKICAgICAgICAgICAgICAgIHBxLnB1c2goe25ld1BsYXllciwgY3VyLmJveCwgY3VyLmcgKyAxLCBoZXVyaXN0aWMoY3VyLmJveCl9KTsKICAgICAgICAgICAgICAgIHBhcmVudFt7bmV3UGxheWVyLCBjdXIuYm94fV0gPSB7Y3VyLnBsYXllciwgY3VyLmJveH07CiAgICAgICAgICAgICAgICBtb3ZlVGFrZW5be25ld1BsYXllciwgY3VyLmJveH1dID0gbW92ZUNoYXJba107CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gIiI7Cn0KCmludCBtYWluKCkgewogICAgaW9zOjpzeW5jX3dpdGhfc3RkaW8oZmFsc2UpOwogICAgY2luLnRpZShudWxscHRyKTsKCiAgICBncmlkLnJlc2l6ZShSKTsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgUjsgaSsrKSB7CiAgICAgICAgY2luID4+IGdyaWRbaV07CiAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBDOyBqKyspIHsKICAgICAgICAgICAgaWYgKGdyaWRbaV1bal0gPT0gJ2EnKSBteVBvcyA9IHtpLCBqfTsKICAgICAgICAgICAgaWYgKGdyaWRbaV1bal0gPT0gJ0EnKSBnb2FsQSA9IHtpLCBqfTsKICAgICAgICAgICAgaWYgKGdyaWRbaV1bal0gPT0gJ0InKSBnb2FsQiA9IHtpLCBqfTsKICAgICAgICB9CiAgICB9CgogICAgY29tcHV0ZURlYWRDb3JuZXJzKCk7CgogICAgdmVjdG9yPFBvcz4gYm94ZXM7CiAgICBmb3IgKGludCByID0gMDsgciA8IFI7IHIrKykKICAgICAgICBmb3IgKGludCBjID0gMDsgYyA8IEM7IGMrKykKICAgICAgICAgICAgaWYgKGdyaWRbcl1bY10gPT0gJ1gnKSBib3hlcy5wdXNoX2JhY2soe3IsIGN9KTsKCiAgICBzdHJpbmcgYmVzdFBhdGg7CiAgICBpbnQgYmVzdERpc3QgPSAxZTk7CgogICAgZm9yIChhdXRvICZib3ggOiBib3hlcykgewogICAgICAgIGlmIChpc0RlYWRDb3JuZXJbYm94LnJdW2JveC5jXSAmJiBib3ggIT0gZ29hbEEpIGNvbnRpbnVlOwogICAgICAgIGludCBkaXN0VG9Cb3ggPSBtYW5oYXR0YW4obXlQb3MsIGJveCk7CiAgICAgICAgaWYgKGRpc3RUb0JveCA+IDIwKSBjb250aW51ZTsgLy8gZmlsdGVyIGZhciBib3hlcwoKICAgICAgICBzdHJpbmcgcGF0aCA9IGFTdGFyQm94KG15UG9zLCBib3gpOwogICAgICAgIGlmICghcGF0aC5lbXB0eSgpICYmIGRpc3RUb0JveCA8IGJlc3REaXN0KSB7CiAgICAgICAgICAgIGJlc3REaXN0ID0gZGlzdFRvQm94OwogICAgICAgICAgICBiZXN0UGF0aCA9IHBhdGg7CiAgICAgICAgfQogICAgfQoKICAgIGlmICghYmVzdFBhdGguZW1wdHkoKSkKICAgICAgICBjb3V0IDw8IGJlc3RQYXRoWzBdIDw8ICJcbiI7CiAgICBlbHNlIHsKICAgICAgICAvLyByYW5kb20gbW92ZSBmYWxsYmFjawogICAgICAgIHZlY3RvcjxpbnQ+IGRpcnMgPSB7MCwgMSwgMiwgM307CiAgICAgICAgcmFuZG9tX3NodWZmbGUoZGlycy5iZWdpbigpLCBkaXJzLmVuZCgpKTsKICAgICAgICBmb3IgKGludCBrIDogZGlycykgewogICAgICAgICAgICBpbnQgbnIgPSBteVBvcy5yICsgZHJba10sIG5jID0gbXlQb3MuYyArIGRjW2tdOwogICAgICAgICAgICBpZiAoIWlzV2FsbChuciwgbmMpKSB7CiAgICAgICAgICAgICAgICBjb3V0IDw8IG1vdmVDaGFyW2tdIDw8ICJcbiI7CiAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjb3V0IDw8ICJVXG4iOyAvLyBkZWZhdWx0CiAgICB9CiAgICByZXR1cm4gMDsKfQ==