1 POJ 1475 Pushing Boxes

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <algorithm>
  6 #include <queue>
  7 #include <vector>
  8 #include <stack>
  9 #include <map>
 10 #include <set>
 11 #include <cmath>
 12 #include <cctype>
 13 #include <ctime>
 14 
 15 using namespace std;
 16 
 17 #define REP(i, n) for (int i = 0; i < (n); ++i)
 18 #define eps 1e-9
 19 #define SZ(x) ((int)x.size())
 20 #define x first
 21 #define y second
 22 #define y1 Y1
 23 
 24 typedef unsigned long long ll;
 25 typedef pair<int, int> pii;
 26 struct Node {
 27     pii s, b; int push, walk;
 28     bool operator < (const Node& rhs) const {
 29         return push > rhs.push || (push == rhs.push && walk > rhs.walk);
 30     }
 31 };
 32 const int maxn = 30;
 33 int n, m, Case = 0;
 34 char G[maxn][maxn], path[maxn * maxn];
 35 pii S, B, T;
 36 bool flag;
 37 int dir[][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
 38 int fa[maxn][maxn][maxn][maxn][5], h[maxn][maxn][maxn][maxn][2];
 39 
 40 bool check(int x, int y) {
 41     return (1 <= x && x <= n && 1 <= y && y <= m && G[x][y] != '#');
 42 }
 43 void print(int x, int y, int len) {
 44     int x1 = T.x, y1 = T.y, fx, fy, fx1, fy1, len_t = len; char c;
 45     while (len--) {
 46         fx = fa[x][y][x1][y1][0]; fy = fa[x][y][x1][y1][1];
 47         fx1 = fa[x][y][x1][y1][2]; fy1 = fa[x][y][x1][y1][3];
 48         c = 'a'; if (fx1 != x1 || fy1 != y1) { c = 'A'; }
 49         if (x - fx == -1) { path[len] = 'N' - 'A' + c; }
 50         else if (x - fx == 1) { path[len] = 'S' - 'A' + c; }
 51         else if (y - fy == -1) { path[len] = 'W' - 'A' + c; }
 52         else { path[len] = 'E' - 'A' + c; }
 53         x = fx; y = fy; x1 = fx1; y1 = fy1;
 54     }
 55     for (int i = 0; i < len_t; ++i) { printf("%c", path[i]); }
 56 }
 57 bool is_best(int x1, int y1, int x2, int y2, int push, int walk) {
 58     if (push != h[x1][y1][x2][y2][0]) { return push < h[x1][y1][x2][y2][0]; }
 59     return walk < h[x1][y1][x2][y2][1];
 60 }
 61 void set_best(int x1, int y1, int x2, int y2, int push, int walk) {
 62     h[x1][y1][x2][y2][0] = push; h[x1][y1][x2][y2][1] = walk;
 63 }
 64 void AStar() {
 65     memset(fa, 0, sizeof(fa)); memset(h, 0x3f3f3f3f, sizeof(h));
 66     priority_queue<Node> q; Node t1, t2;
 67     t1.s = S; t1.b = B; t1.push = t1.walk = 0; q.push(t1);
 68     while (!q.empty()) {
 69         t1 = q.top(); q.pop();
 70         if (t1.b == T) { print(t1.s.x, t1.s.y, t1.push + t1.walk); flag = true; break; }
 71         for (int i = 0; i < 4; ++i) {
 72             t2 = t1; t2.s.x += dir[i][0]; t2.s.y += dir[i][1];
 73             if (!check(t2.s.x, t2.s.y)) { continue; }
 74             if (t2.s == t2.b) {
 75                 t2.b.x += dir[i][0]; t2.b.y += dir[i][1];
 76                 if (!check(t2.b.x, t2.b.y)) { continue; } ++t2.push;
 77             } else { ++t2.walk; }
 78             if (!is_best(t2.s.x, t2.s.y, t2.b.x, t2.b.y, t2.push, t2.walk)) { continue; }
 79             fa[t2.s.x][t2.s.y][t2.b.x][t2.b.y][0] = t1.s.x;
 80             fa[t2.s.x][t2.s.y][t2.b.x][t2.b.y][1] = t1.s.y;
 81             fa[t2.s.x][t2.s.y][t2.b.x][t2.b.y][2] = t1.b.x;
 82             fa[t2.s.x][t2.s.y][t2.b.x][t2.b.y][3] = t1.b.y;
 83             set_best(t2.s.x, t2.s.y, t2.b.x, t2.b.y, t2.push, t2.walk); q.push(t2);
 84         }
 85     }
 86 }
 87 
 88 int main() {
 89 #ifdef __AiR_H
 90     freopen("in.txt", "r", stdin);
 91 //    freopen("out.txt", "w", stdout);
 92 #endif // __AiR_H
 93     while (scanf("%d %d", &n, &m) != EOF) {
 94         if (n == 0 && m == 0) { break; }
 95         for (int i = 1; i <= n; ++i) {
 96             scanf("%s", G[i] + 1);
 97             for (int j = 1; j <= m; ++j) {
 98                 if (G[i][j] == 'S') { S.x = i; S.y = j; }
 99                 else if (G[i][j] == 'B') { B.x = i; B.y = j; }
100                 else if (G[i][j] == 'T') { T.x = i; T.y = j; }
101             }
102         }
103         printf("Maze #%d\n", ++Case); flag = false; AStar();
104         if (!flag) { printf("Impossible."); } printf("\n\n");
105     }
106 #ifdef __AiR_H
107     printf("Time used = %.2fs\n", (double)clock() / CLOCKS_PER_SEC);
108 #endif // __AiR_H
109     return 0;
110 }
View Code