POJ 1475 推箱
时限:n.2000MS | 内存限制:n.131072K | |||
提交材料共计: 6600 | 接受: 2263 | 特别法官 |
描述
想象一下你站在一个二维迷宫里,由方形细胞组成,它们可能或可能不会充满岩石。你可以在一个台阶上移动北、南、东或西一个单元。这些动作叫做步行。
其中一个空单元包含一个盒子,它可以通过站在盒子旁边移动到相邻的自由单元格,然后移动到盒子的方向上。这样的举动叫做推。盒子不能用任何其他方式移动,而不是推,这意味着如果你把它推到角落里,你就再也无法把它从角落里弄出来了。
其中一个空单元被标记为目标单元格。你的工作就是通过一系列步行和推来把盒子带到目标细胞里。由于盒子很重,你想尽量减少推的次数。你能写一个程序来写出最好的这个序列吗?
其中一个空单元包含一个盒子,它可以通过站在盒子旁边移动到相邻的自由单元格,然后移动到盒子的方向上。这样的举动叫做推。盒子不能用任何其他方式移动,而不是推,这意味着如果你把它推到角落里,你就再也无法把它从角落里弄出来了。
其中一个空单元被标记为目标单元格。你的工作就是通过一系列步行和推来把盒子带到目标细胞里。由于盒子很重,你想尽量减少推的次数。你能写一个程序来写出最好的这个序列吗?
输入
输入包含了几个迷宫的描述。每个迷宫描述都是从一个包含两个整数r和c(两个整数)开始的一行,表示迷宫的行数和列数。
下面是每个包含c字符的r行。每个字符描述迷宫的一个单元格。一个满是岩石的单元格由‘#’表示,一个空单元由‘.’表示。您的起始位置由“`S”、“方框的起始位置”和“`t”的目标单元构成。
输入以两个零终止r和c。
下面是每个包含c字符的r行。每个字符描述迷宫的一个单元格。一个满是岩石的单元格由‘#’表示,一个空单元由‘.’表示。您的起始位置由“`S”、“方框的起始位置”和“`t”的目标单元构成。
输入以两个零终止r和c。
输出量
对于输入中的每个迷宫,首先打印迷宫的数目,如示例输出所示。然后,如果不可能将该框带到目标单元格,则打印“不可能”。
否则,输出一个最小化推数的序列。如果有不止一个这样的序列,选择最小化总移动数(行走和推)数的那个。如果仍然有不止一个这样的序列,任何一个都可以接受。
将序列作为字符串字符n、s、e、w、n、s、e和w等字符,大写字母表示推,小写字母表示行走,不同字母代表方向北、南、东、西。
在每个测试用例之后输出一个空行。
否则,输出一个最小化推数的序列。如果有不止一个这样的序列,选择最小化总移动数(行走和推)数的那个。如果仍然有不止一个这样的序列,任何一个都可以接受。
将序列作为字符串字符n、s、e、w、n、s、e和w等字符,大写字母表示推,小写字母表示行走,不同字母代表方向北、南、东、西。
在每个测试用例之后输出一个空行。
样本输入
1 7
SB....T
1 7
SB..#.T
7 11
###########
#T##......#
#.#.#..####
#....B....#
#.######..#
#.....S...#
###########
8 4
....
.##.
.#..
.#..
.#.B
.##S
....
###T
0 0
样本输出
Maze #1
EEEEE
Maze #2
Impossible.
Maze #3
eennwwWWWWeeeeeesswwwwwwwnNN
Maze #4
swwwnnnnnneeesssSSS
来源
#include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define MAXN 30 using namespace std; string ans; char map[MAXN][MAXN]; bool vis[MAXN][MAXN]; char dc[4]={'W','E','N','S'}; char dc2[4]={'w','e','n','s'}; int r,c,box_x,box_y,pson_x,pson_y; int dir[4][2]={0,-1,0,1,-1,0,1,0}; struct node{ int x,y;string path; }; struct nond{ int px,py,bx,by;string path; }; bool check(int x,int y){ return map[x][y]!='#'; } bool bfs2(int nx,int ny,int tx,int ty,int kx,int ky,string &pans){ queue<node>q; memset(vis,0,sizeof(vis)); vis[nx][ny]=vis[kx][ky]=true; node now,tmp; now.x=nx;now.y=ny; now.path="";q.push(now); while(!q.empty()){ now=q.front();q.pop(); if(now.x==tx&&now.y==ty){ pans=now.path; return true; } for(int i=0;i<4;i++){ int zx=now.x+dir[i][0]; int zy=now.y+dir[i][1]; if(check(zx,zy)&&!vis[zx][zy]){ vis[zx][zy]=true; tmp.x=zx;tmp.y=zy; tmp.path=now.path+dc2[i]; q.push(tmp); } } } return false; } bool bfs(){ queue<nond>q; memset(vis,0,sizeof(vis)); vis[box_x][box_y]=true; nond tmp,now; now.px=pson_x;now.py=pson_y; now.bx=box_x;now.by=box_y; now.path="";q.push(now); while(!q.empty()){ now=q.front();q.pop(); for(int i=0;i<4;i++){ int nx=now.bx+dir[i][0]; int ny=now.by+dir[i][1]; int tx=now.bx-dir[i][0]; int ty=now.by-dir[i][1]; string pans=""; if(check(nx,ny)&&check(tx,ty)&&!vis[nx][ny]){ if(bfs2(now.px,now.py,tx,ty,now.bx,now.by,pans)){ vis[nx][ny]=true; tmp.px=now.bx; tmp.py=now.by; tmp.bx=nx;tmp.by=ny; tmp.path=now.path+pans+dc[i]; if(map[nx][ny]=='T'){ ans=tmp.path; return true; } q.push(tmp); } } } } return false; } int main(){ int cs=1; while(scanf("%d %d",&r,&c)&&r!=0&&c!=0){ memset(map,'#',sizeof(map)); for(int i=1;i<=r;i++){ for(int j=1;j<=c;j++){ cin>>map[i][j]; if(map[i][j]=='B'){ box_x=i;box_y=j; } if(map[i][j]=='S'){ pson_x=i;pson_y=j; } } } printf("Maze #%d\n",cs++); if(bfs()) cout<<ans<<endl; else puts("Impossible.\n"); } }
细雨斜风作晓寒。淡烟疏柳媚晴滩。入淮清洛渐漫漫。
雪沫乳花浮午盏,蓼茸蒿笋试春盘。人间有味是清欢。