//Memory 164K 297MS
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<string>
using namespace std;
int direction[4][2] = {{-1, 0},//方向数组
{1, 0},
{0, -1},
{0, 1}};
char peopleWalk[] = {'n', 's', 'w', 'e'};
char peoplePushBox[] = {'N', 'S', 'W', 'E'};
bool mark[21][21][4];//标记箱子四周的位置时候是否被使用
int visit[21][21];//标记人走过的位置
char arr[21][21];//存储地图数组
int row, col;//行和列
struct Box//盒子
{ //peopleX,peopleY为箱子的位置确定后,人的位置
int x, y, peopleX,peopleY;
string road;
} nowBox, finalBox; //当前盒子的位置,最终盒子的位置
struct People//人
{
int x, y;
string road;
} nowPeople, finalPeople;
bool boundary(int x, int y) {
return x >= 0 && x < row && y >= 0 && y < col;
}
//aimX,aimY为人要到达的位置 boxX,boxY为当前盒子的位置 beginPeopleX,beginPeopleY为一开始人的位置
//当前人的一开始的位置,是否能够到达目的位置
bool bfs2(int aimX, int aimY, int boxX, int boxY, int beginPeopleX, int beginPeopleY)
{
queue<People> qP;
//人要到达的这个位置,如果越界或者是墙
if (!boundary(aimX,aimY) || arr[aimX][aimY] == '#')
return false;
//将人的刚开始的位置传递给nowPeople
nowPeople.x = beginPeopleX;
nowPeople.y = beginPeopleY;
//记录人的路径
nowPeople.road = "";
memset(visit, 0, sizeof(visit));
//将盒子的位置和人开始的位置赋值为1
visit[boxX][boxY] = 1;
visit[beginPeopleX][beginPeopleY] = 1;
qP.push(nowPeople);
while (!qP.empty()) {
nowPeople = qP.front();
qP.pop();
//人可以到达理论位置
if (nowPeople.x == aimX && nowPeople.y == aimY)
return true;
//遍历4个方向
for (int i = 0; i < 4; i++) {
//finalPeople存储人的实际位置
//nowPeople存储人的之前的位置
finalPeople.x = nowPeople.x + direction[i][0];
finalPeople.y = nowPeople.y + direction[i][1];
if (boundary(finalPeople.x, finalPeople.y) && !visit[finalPeople.x][finalPeople.y] &&
arr[finalPeople.x][finalPeople.y] != '#') {
finalPeople.road = nowPeople.road + peopleWalk[i];//记录走过的路径
visit[finalPeople.x][finalPeople.y] = 1;
qP.push(finalPeople);
}
}
}
return false;
}
bool bfs1(int xOfBox, int yOfBox, int xOfStart, int yOfStart, int xOfTarget, int yOfTarget) {
queue<Box> qB;
//记录盒子一开始的位置
nowBox.x = xOfBox;
nowBox.y = yOfBox;
//初始化路径
//后续累加路径
nowBox.road = "";
//记录人一开始的位置
nowBox.peopleX = xOfStart;
nowBox.peopleY = yOfStart;
qB.push(nowBox);
while (!qB.empty()) {
nowBox = qB.front();
qB.pop();
if (nowBox.x == xOfTarget && nowBox.y == yOfTarget)
return true;
for (int i = 0; i < 4; i++) //盒子周围的四个方向;
{
//方向n s w e
finalBox.x = nowBox.x + direction[i][0];
finalBox.y = nowBox.y + direction[i][1];
if (boundary(finalBox.x, finalBox.y) && !mark[finalBox.x][finalBox.y][i] &&
arr[finalBox.x][finalBox.y] != '#') {
//如果能推到finalPeople,则需要判断人是否能到达,它的上一个点
if (bfs2(nowBox.x - direction[i][0], nowBox.y - direction[i][1], nowBox.x, nowBox.y, nowBox.peopleX,
nowBox.peopleY)) {
//若bfs2返回的是true
//那就说明人可以推动箱子
//则进行推箱子
//finalBox存储实际的综合位置
//nowBox存储之前的综合位置
finalBox.peopleX = nowBox.x;//推完箱子后,人的位置在箱子上
finalBox.peopleY = nowBox.y;
//存储之前的路径(人走的路径和人推箱子的路径)
finalBox.road = nowBox.road + nowPeople.road + peoplePushBox[i];//当前的加上推箱子的加上目前挨着推的;
//标记箱子目前方向旁边的格子被使用
mark[finalBox.x][finalBox.y][i] = true;
qB.push(finalBox);
}
}
}
}
return false;
}
void run() {
int caseNum = 1;
int boxX, boxY, startX, startY, targetX, targetY;
while (scanf("%d %d", &row, &col), row, col) {
memset(mark, false, sizeof(mark));
for (int i = 0; i < row; i++)
for (int j = 0; j < col; j++) {
scanf(" %c", &arr[i][j]);
//记录人开始的位置
if (arr[i][j] == 'S') {
startX = i;
startY = j;
}
//记录目标位置
if (arr[i][j] == 'T') {
targetX = i;
targetY = j;
}
//记录箱子开始的位置
if (arr[i][j] == 'B') {
boxX = i;
boxY = j;
}
}
printf("Maze #%d\n", caseNum++);
cout << (bfs1(boxX, boxY, startX, startY, targetX, targetY) ? nowBox.road + "\n\n" : "Impossible.\n\n");
}
}
int main() {
run();
return 0;
}
//简洁版
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<string>
using namespace std;
int direction[4][2] = {{-1, 0},//方向数组
{1, 0},
{0, -1},
{0, 1}};
char peopleWalk[] = {'n', 's', 'w', 'e'};
char peoplePushBox[] = {'N', 'S', 'W', 'E'};
bool mark[21][21][4];
int visit[21][21];
char arr[21][21];
int row, col;
struct Box
{
int x, y, peopleX,peopleY;
string road;
} nowBox, finalBox;
struct People
{
int x, y;
string road;
} nowPeople, finalPeople;
bool boundary(int x, int y) {
return x >= 0 && x < row && y >= 0 && y < col;
}
bool bfs2(int aimX, int aimY, int boxX, int boxY, int beginPeopleX, int beginPeopleY)
{
queue<People> qP;
if (!boundary(aimX,aimY) || arr[aimX][aimY] == '#')
return false;
nowPeople.x = beginPeopleX;
nowPeople.y = beginPeopleY;
nowPeople.road = "";
memset(visit, 0, sizeof(visit));
visit[boxX][boxY] = 1;
visit[beginPeopleX][beginPeopleY] = 1;
qP.push(nowPeople);
while (!qP.empty()) {
nowPeople = qP.front();
qP.pop();
if (nowPeople.x == aimX && nowPeople.y == aimY)
return true;
for (int i = 0; i < 4; i++) {
finalPeople.x = nowPeople.x + direction[i][0];
finalPeople.y = nowPeople.y + direction[i][1];
if (boundary(finalPeople.x, finalPeople.y) && !visit[finalPeople.x][finalPeople.y] &&
arr[finalPeople.x][finalPeople.y] != '#') {
finalPeople.road = nowPeople.road + peopleWalk[i];
visit[finalPeople.x][finalPeople.y] = 1;
qP.push(finalPeople);
}
}
}
return false;
}
bool bfs1(int xOfBox, int yOfBox, int xOfStart, int yOfStart, int xOfTarget, int yOfTarget) {
queue<Box> qB;
nowBox.x = xOfBox;
nowBox.y = yOfBox;
nowBox.road = "";
nowBox.peopleX = xOfStart;
nowBox.peopleY = yOfStart;
qB.push(nowBox);
while (!qB.empty()) {
nowBox = qB.front();
qB.pop();
if (nowBox.x == xOfTarget && nowBox.y == yOfTarget)
return true;
for (int i = 0; i < 4; i++)
{
finalBox.x = nowBox.x + direction[i][0];
finalBox.y = nowBox.y + direction[i][1];
if (boundary(finalBox.x, finalBox.y) && !mark[finalBox.x][finalBox.y][i] &&
arr[finalBox.x][finalBox.y] != '#') {
if (bfs2(nowBox.x - direction[i][0], nowBox.y - direction[i][1], nowBox.x, nowBox.y, nowBox.peopleX,
nowBox.peopleY)) {
finalBox.peopleX = nowBox.x;
finalBox.peopleY = nowBox.y;
finalBox.road = nowBox.road + nowPeople.road + peoplePushBox[i];
mark[finalBox.x][finalBox.y][i] = true;
qB.push(finalBox);
}
}
}
}
return false;
}
void run() {
int caseNum = 1;
int boxX, boxY, startX, startY, targetX, targetY;
while (scanf("%d %d", &row, &col), row, col) {
memset(mark, false, sizeof(mark));
for (int i = 0; i < row; i++)
for (int j = 0; j < col; j++) {
scanf(" %c", &arr[i][j]);
if (arr[i][j] == 'S') {
startX = i;
startY = j;
}
if (arr[i][j] == 'T') {
targetX = i;
targetY = j;
}
if (arr[i][j] == 'B') {
boxX = i;
boxY = j;
}
}
printf("Maze #%d\n", caseNum++);
cout << (bfs1(boxX, boxY, startX, startY, targetX, targetY) ? nowBox.road + "\n\n" : "Impossible.\n\n");
}
}
int main() {
run();
return 0;
}