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. Java小应用程序Applet,画布上新建按钮和文本

    <pre name="code" class="java">package com.hx; import java.applet.*; import ...

  2. RHEL5.8设置OpenSSH的X11 Forwarding功能

    X11的Forwarding功能需要在SSH中进行设置,RedHat Enterprise Linux5.8默认使用的而是OpenSSH,现将设置方法记录如下: OpenSSH配置文件路径: /etc ...

  3. 开源免费ERP/CRM/SCM:iDempiere 2.0 安装配置

    首先简单介绍一下iDempiere:iDempiere是一款Java平台的基于Compiere/ADempiere的​开源企业级开源ERP/CRM/SCM系统​, 由于是在ADempiere基础上用O ...

  4. MSTest、NUnit、xUnit.net 属性和断言对照表

    MSTest.NUnit.xUnit.net 属性对照表 MSTest NUnit xUnit.net Comments [TestMethod] [Test] [Fact] Marks a test ...

  5. SQL Server 重新初始化系统数据库中的单引号问题

    在最近的数据库跨机房迁移中,由于硬件的限制,需要滚动式地将数据库一台台迁移到新机房,先在新机房搭建一个新环境,将数据迁移过去,再将旧机房的机器下架搬到新机房,重新配置后用于下一轮的升级,重新配置过程中 ...

  6. memcached(二)事件模型源码分析

    memcachedd事件模型 在memcachedd中,作者为了专注于缓存的设计,使用了libevent来开发事件模型.memcachedd的时间模型同nginx的类似,拥有一个主进行(master) ...

  7. [ucgui] 子窗口父窗口

    它创建了3个窗口: 第一个作为桌面的子窗口 第二个作为第一个窗口的子窗口 第三个作为第二个窗口的子窗口 窗口创建后,使用WM_ForEachDesc()在其父窗口中移动各个窗口: static voi ...

  8. 从配置sublimeClang插件中学到的

    1.不害怕失败的关键在于要事先为失败准备补救措施.2.人们害怕内部结构复杂的东西出错,并以自己缺乏对内部结构的认识为理由而放弃查错.其实某些情况下根本无需对内部结构有多么深入的认识,只需从外部观察就够 ...

  9. YUI Compressor for Sublime text2

    YUI Compressor 是一个用来压缩 JS 和 CSS 文件的工具,采用Java开发. 最近压缩文件,常使用在线压缩的方式来压缩文件,一来多有不便,二来如果没有网络,只能搁置了.本文来描述如何 ...

  10. CLIQUE 聚类算法以及Java实现+多线程

    CLIQUE(Clustering In QUEst)是一种简单的基于网格的聚类方法,用于发现子空间中基于密度的簇.CLIQUE把每个维划分成不重叠的区间,从而把数据对象的整个嵌入空间划分成单元.它使 ...