POJ 1475 推箱

时限:n.2000MS   内存限制:n.131072K
提交材料共计: 6600   接受: 2263   特别法官

描述

想象一下你站在一个二维迷宫里,由方形细胞组成,它们可能或可能不会充满岩石。你可以在一个台阶上移动北、南、东或西一个单元。这些动作叫做步行。
其中一个空单元包含一个盒子,它可以通过站在盒子旁边移动到相邻的自由单元格,然后移动到盒子的方向上。这样的举动叫做推。盒子不能用任何其他方式移动,而不是推,这意味着如果你把它推到角落里,你就再也无法把它从角落里弄出来了。

其中一个空单元被标记为目标单元格。你的工作就是通过一系列步行和推来把盒子带到目标细胞里。由于盒子很重,你想尽量减少推的次数。你能写一个程序来写出最好的这个序列吗?

输入

输入包含了几个迷宫的描述。每个迷宫描述都是从一个包含两个整数r和c(两个整数)开始的一行,表示迷宫的行数和列数。

下面是每个包含c字符的r行。每个字符描述迷宫的一个单元格。一个满是岩石的单元格由‘#’表示,一个空单元由‘.’表示。您的起始位置由“`S”、“方框的起始位置”和“`t”的目标单元构成。

输入以两个零终止r和c。

输出量

对于输入中的每个迷宫,首先打印迷宫的数目,如示例输出所示。然后,如果不可能将该框带到目标单元格,则打印“不可能”。

否则,输出一个最小化推数的序列。如果有不止一个这样的序列,选择最小化总移动数(行走和推)数的那个。如果仍然有不止一个这样的序列,任何一个都可以接受。

将序列作为字符串字符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");
    }
}
木有AC代码,不想调了。

 

posted @ 2018-04-29 16:05  一蓑烟雨任生平  阅读(255)  评论(0编辑  收藏  举报