POJ 1475 Pushing Boxes(推箱子游戏 内嵌BFS)

题意:就特么是推箱子。

思路:我们的目标是让箱子到达目标地点,所以我们就主要是对箱子进行BFS,然后我们在这之后判断一下人可不可以推动这个箱子。然后记录下人挪动的步骤。当然我们用3维数组对箱子的移动进行判重,第三维度记录箱子是从哪个方向移动过来的。

#include <cstdio>
#include <iostream>
#include <queue>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;

struct node
{
    int sx,sy;            //人的坐标
    int bx,by;           //box 坐标
    vector <char> ans;   //记录路径
};


int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};
char op[]={'n','s','w','e'};
int n,m;

int map[25][25];
int vb[25][25][4];
int vs[25][25];//

void debug(node t)   //调试函数
{
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(i==t.bx && j==t.by)
            {printf("B");continue;}
            else if(i==t.sx && j==t.sy)
            {printf("S");continue;}

            if(map[i][j]==9)printf("X");
            else if(map[i][j]==0)printf("#");
            else if(map[i][j]==1)printf(".");
        }
        putchar(10);
    }
    putchar(10);
}


bool bfss(node &t,int mx,int my)   //对人进行BFS 判断是否可以推动  这里传了引用,为了改变人的位置
{
    if(t.sx==mx && t.sy==my)
    {
        t.sx=t.bx;
        t.sy=t.by;
        return true;
    }
    node w,e;
    memset(vs,0,sizeof(vs));
    queue<node>QQ;
    w=t;
    QQ.push(w);
    vs[w.sx][w.sy]=1;
    while(!QQ.empty())
    {
        w=QQ.front();
        QQ.pop();


        for(int k=0;k<4;k++)
        {
            e=w;

            int x=e.sx+dx[k];
            int y=e.sy+dy[k];

            if(map[x][y]==0)continue;

            if(x==mx && y==my)
            {
                e.sx=e.bx;
                e.sy=e.by;
                e.ans.push_back(op[k]);
                t=e;
                return true;
            }

            if(map[x][y]!=0 && vs[x][y]!=1 && (x!=e.bx || y!=e.by))
            {
                e.sx=x;
                e.sy=y;
                e.ans.push_back(op[k]);

                vs[x][y]=1;
                QQ.push(e);
            }
        }
    }
    return false;
}

void bfsb(node t)
{
    memset(vb,0,sizeof(vb));
    queue<node>Q;
    node w,e;
    Q.push(t);
    while(!Q.empty())
    {
        w=Q.front();
        Q.pop();
        //debug(w);
        for(int k=0;k<4;k++)
        {
            e=w;

            int x=e.bx+dx[k];
            int y=e.by+dy[k];

            int mx=e.bx-dx[k];
            int my=e.by-dy[k];

            if(map[mx][my]==0)continue;
            if(map[x][y]!=0 &&  vb[x][y][k]!=1)
            {          
                if(bfss(e,mx,my))
                {
                    e.ans.push_back(op[k]-32);
                    e.bx=x;
                    e.by=y;
                    vb[x][y][k]=1;
                    Q.push(e);
                 //   debug(e);
                }
                else continue;   //因为这个语句所以没有过下面所给的第二个样例   因为在人无法到达理想位置的时候   就不可以挪动箱子 即使箱子就在目标地点的旁边     
                if(map[x][y]==9)
                {
                    for(int s=0;s<e.ans.size();s++)
                    printf("%c",e.ans[s]);
                    //printf("%c",op[k]-32);
                    putchar(10);
                    return ;
                }
            }
        }
    }
    printf("Impossible.\n");
}
int main()
{
    node w;
    int CASE=1;
    while(scanf("%d%d",&n,&m)!=EOF && n && m)
    {
        getchar();
        memset(map,0,sizeof(map));
        char ch;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                scanf("%c",&ch);
                if(ch=='#')map[i][j]=0;
                else if(ch=='.')map[i][j]=1;
                else if(ch=='T')map[i][j]=9;
                else if(ch=='S'){w.sx=i;w.sy=j;map[i][j]=1;}
                else if(ch=='B'){w.bx=i;w.by=j;map[i][j]=1;}
            }
            getchar();
        }
        printf("Maze #%d\n",CASE++);
        bfsb(w);
        putchar(10);
    }
    return 0;
}


/*


6 7
ST.....
....#..
.......
....B..
...#.#.
...#...


11 19
....#####..........
....#...#..........
....#...#..........
..###..B##.........
..#......#.........
###.#.##.#...######
#...#.##.#####T...#
#.................#
####..###.#S##....#
...#......#########
...########........
Maze #1
nwwwnnnwwnneSwswssseeennnWWnwSSSnnwwssseEEEEEEEEEEseNenW


4 4
#T##
#.BS
#.#.
#...
*/



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值