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 }