• 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
    ",cs++);
            if(bfs())    cout<<ans<<endl;
            else    puts("Impossible.
    ");
        }
    }
    木有AC代码,不想调了。
    细雨斜风作晓寒。淡烟疏柳媚晴滩。入淮清洛渐漫漫。 雪沫乳花浮午盏,蓼茸蒿笋试春盘。人间有味是清欢。
  • 相关阅读:
    29 求和
    28 跳转控制语句 goto
    27 跳转控制语句 continue
    26 跳转控制语句 break
    25 打印金字塔
    24 打印九九乘法表
    23 多重循环控制
    22 do-while 循环
    21 while 循环
    20 for循环控制
  • 原文地址:https://www.cnblogs.com/cangT-Tlan/p/8971193.html
Copyright © 2020-2023  润新知