Description

Imagine you are standing inside a two-dimensional maze composed of square cells which may or may not be filled with rock. You can move north, south, east or west one cell at a step. These moves are called walks. 

One of the empty cells contains a box which can be moved to an adjacent free cell by standing next to the box and then moving in the direction of the box. Such a move is called a push. The box cannot be moved in any other way than by pushing, which means that
if you push it into a corner you can never get it out of the corner again. 



One of the empty cells is marked as the target cell. Your job is to bring the box to the target cell by a sequence of walks and pushes. As the box is very heavy, you would like to minimize the number of pushes. Can you write a program that will work out the
best such sequence? 

Input

The input contains the descriptions of several mazes. Each maze description starts with a line containing two integers r and c (both <= 20) representing the number of rows and columns of the maze. 



Following this are r lines each containing c characters. Each character describes one cell of the maze. A cell full of rock is indicated by a `#' and an empty cell is represented by a `.'. Your starting position is symbolized by `S', the starting position of
the box by `B' and the target cell by `T'. 



Input is terminated by two zeroes for r and c. 

Output

For each maze in the input, first print the number of the maze, as shown in the sample output. Then, if it is impossible to bring the box to the target cell, print ``Impossible.''. 



Otherwise, output a sequence that minimizes the number of pushes. If there is more than one such sequence, choose the one that minimizes the number of total moves (walks and pushes). If there is still more than one such sequence, any one is acceptable. 



Print the sequence as a string of the characters N, S, E, W, n, s, e and w where uppercase letters stand for pushes, lowercase letters stand for walks and the different letters stand for the directions north, south, east and west. 



Output a single blank line after each test case. 

Sample Input

1 7
SB....T
1 7
SB..#.T
7 11
###########
#T##......#
#.#.#..####
#....B....#
#.######..#
#.....S...#
###########
8 4
....
.##.
.#..
.#..
.#.B
.##S
....
###T
0 0

Sample Output

Maze #1
EEEEE Maze #2
Impossible. Maze #3
eennwwWWWWeeeeeesswwwwwwwnNN Maze #4
swwwnnnnnneeesssSSS

思路:用一个四维数组分别记录箱子和人的位置。son数组记录上一个节点,用优先队列让推的次数最小的先出队。递归输出路径。

#include <cstdio>
#include <queue>
using namespace std; struct S{
int x,y,bx,by,id,pcnt,acnt;
friend bool operator<(struct S a,struct S b);
}t; bool operator<(struct S a,struct S b)
{
if(a.pcnt!=b.pcnt) return a.pcnt>b.pcnt;
else return a.acnt>b.acnt;
} priority_queue<struct S>que; char mp[20][21];
bool vis[20][20][20][20];
int nxt[4][2]={{0,1},{1,0},{0,-1},{-1,0}},val[1000000],son[1000000],idx; void dfs(int x)
{
if(son[x]!=-1)
{
dfs(son[x]);
printf("%c",val[x]);
}
} int main()
{
int n,m,i,j,p,q,ex,ey,casenum=1; while(~scanf("%d%d",&n,&m) && n)
{
printf("Maze #%d\n",casenum++); for(i=0;i<n;i++) scanf("%s",mp[i]); for(i=0;i<n;i++) for(j=0;j<m;j++) for(p=0;p<n;p++) for(q=0;q<m;q++) vis[i][j][p][q]=0; for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
if(mp[i][j]=='S') mp[i][j]='.',t.x=i,t.y=j;
if(mp[i][j]=='B') mp[i][j]='.',t.bx=i,t.by=j;
if(mp[i][j]=='T') mp[i][j]='.',ex=i,ey=j;
}
} vis[t.x][t.y][t.bx][t.by]=1; idx=1; t.id=0;
son[0]=-1;
t.pcnt=0;
t.acnt=0; while(!que.empty()) que.pop(); que.push(t); while(!que.empty())
{
t=que.top(); if(t.bx==ex && t.by==ey)
{
dfs(t.id);
printf("\n"); break;
} for(i=0;i<4;i++)
{
t.x+=nxt[i][0];
t.y+=nxt[i][1]; if(t.x>=0 && t.x<n && t.y>=0 && t.y<m && mp[t.x][t.y]=='.')
{
if(t.x==t.bx && t.y==t.by)//推箱子
{
t.bx+=nxt[i][0];
t.by+=nxt[i][1]; if(t.bx>=0 && t.bx<n && t.by>=0 && t.by<m && mp[t.bx][t.by]=='.')
{
if(!vis[t.x][t.y][t.bx][t.by])
{
vis[t.x][t.y][t.bx][t.by]=1; int oldid=t.id; son[idx]=t.id;
t.id=idx;
t.pcnt++;
t.acnt++; if(i==0) val[idx]='E';
if(i==1) val[idx]='S';
if(i==2) val[idx]='W';
if(i==3) val[idx]='N'; que.push(t); t.pcnt--;
t.acnt--;
idx++; t.id=oldid;
}
} t.bx-=nxt[i][0];
t.by-=nxt[i][1];
}
else//不推箱子
{
if(!vis[t.x][t.y][t.bx][t.by])
{
vis[t.x][t.y][t.bx][t.by]=1; int oldid=t.id; son[idx]=t.id;
t.id=idx;
t.acnt++; if(i==0) val[idx]='e';
if(i==1) val[idx]='s';
if(i==2) val[idx]='w';
if(i==3) val[idx]='n'; que.push(t); t.acnt--;
idx++; t.id=oldid;
}
}
} t.x-=nxt[i][0];
t.y-=nxt[i][1];
} que.pop();
} if(que.empty()) printf("Impossible.\n"); printf("\n");
}
}

POJ-1475-Pushing Boxes(BFS)的更多相关文章

  1. POJ 1475 Pushing Boxes 搜索- 两重BFS

    题目地址: http://poj.org/problem?id=1475 两重BFS就行了,第一重是搜索箱子,第二重搜索人能不能到达推箱子的地方. AC代码: #include <iostrea ...

  2. poj 1475 Pushing Boxes 推箱子(双bfs)

    题目链接:http://poj.org/problem?id=1475 一组测试数据: 7 3 ### .T. .S. #B# ... ... ... 结果: //解题思路:先判断盒子的四周是不是有空 ...

  3. (poj 1475) Pushing Boxes

    Imagine you are standing inside a two-dimensional maze composed of square cells which may or may not ...

  4. [poj P1475] Pushing Boxes

    [poj P1475] Pushing Boxes Time Limit: 2000MS   Memory Limit: 131072K   Special Judge Description Ima ...

  5. HDU 1475 Pushing Boxes

    Pushing Boxes Time Limit: 2000ms Memory Limit: 131072KB This problem will be judged on PKU. Original ...

  6. Pushing Boxes POJ - 1475 (嵌套bfs)

    Imagine you are standing inside a two-dimensional maze composed of square cells which may or may not ...

  7. POJ1475 Pushing Boxes(BFS套BFS)

    描述 Imagine you are standing inside a two-dimensional maze composed of square cells which may or may ...

  8. poj 1475 || zoj 249 Pushing Boxes

    http://poj.org/problem?id=1475 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=249 Pushin ...

  9. 『Pushing Boxes 双重bfs』

    Pushing Boxes Description Imagine you are standing inside a two-dimensional maze composed of square ...

  10. Pushing Boxes(广度优先搜索)

    题目传送门 首先说明我这个代码和lyd的有点不同:可能更加复杂 既然要求以箱子步数为第一关键字,人的步数为第二关键字,那么我们可以想先找到箱子的最短路径.但单单找到箱子的最短路肯定不行啊,因为有时候不 ...

随机推荐

  1. 如何优化cocos2d程序的内存使用和程序大小:第一部分

    译者: 在我完成第一个游戏项目的时候,我深切地意识到“使用cocos2d来制作游戏的开发者们,他们大多会被cocos2d的内存问题所困扰”.而我刚开始接触cocos2d的时候,社区里面的人们讨论了一个 ...

  2. OpenGL(四)——有用的函数

    概述 1. reshape 定义窗口和图像的映射关系,使在不以纵横比4:3调整窗口大小时,图像不会失真 函数 1. ReShape 如果变更后的窗体的横纵比大于4/3,需要以高为基数,宽为高*4/3, ...

  3. 微信小程序事件始末及相关资料整理

    转载请注明来源:前端之巅 微信公众号 小道消息 昨晚(9月21日晚)10:51,冯大辉在他的知名微信公众号小道消息上发了一篇7字标题的文章<微信应用号来了>,并加了"微信是一个操 ...

  4. .NET 实现自定义ContextUser的Identity和Principal实现自定义用户信息,权限验证。

    备用收藏,http://blog.csdn.net/msdnxgh/article/details/6894885 .NET 实现自定义ContextUser的Identity和Principal 在 ...

  5. 工资低的.Net程序员,活该你工资低

    这两天博客园上关于“.Net工资低”的讨论挺多的,让我不禁想起一句话“拉不出屎来怪地球没引力”. 那些抱怨“做.Net工作三年了月薪才6千,我的同学做Java现在都一万二”的哥们,你问问自己“我会什么 ...

  6. log4net简单配置内容

    首先将log4net.dll下载来,添加到项目引用中: 在assembly文件最后面加(其实没关系的): [assembly: log4net.Config.XmlConfigurator(Confi ...

  7. [Xamarin] 透過WebClient跟網路取得資料 (转帖)

    之前寫過一篇文章,關於在Android上面取得資料 透過GET方式傳資料給Server(含解決中文編碼問題) 我們來回顧一下 Android 端的Code: 有沒有超多,如果是在Xaramin下面,真 ...

  8. Orleans中的Timer和Reminder

    Timers and Reminder 定时器和提醒器 Orleans runtime 允许开发人员通过一种叫做timer和另一种叫做reminder的机制为grain添加周期性行为.接下来我分别为大 ...

  9. 关于CSS中清除浮动的方法

    在使用CSS样式时会经常使用到浮动(float),这时如果没有清除浮动就会造成很多怪异的现象,因此对父级元素清除浮动是必须要做的,这样也是书写CSS的一个良好习惯. 目前常用的方法大致有三种. (1) ...

  10. [MFC] MFC 用mciSendString加载WAV资源文件

    @ - @     FIRDST:为什么不用路径加载? 因为mciSendString函数不支持加载资源文件里的WAV资源,如果按路径加载,那么你的WAV就暴露在exe之外,无法实现音频资源的很好保护 ...