码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 1254 (经典游戏)推箱子 BFS+dfs

时间:2014-08-06 19:07:32      阅读:238      评论:0      收藏:0      [点我收藏+]

标签:c++

Problem Description
推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N的房间里有一个箱子和一个搬运工,搬运工的工作就是把箱子推到指定的位置,注意,搬运工只能推箱子而不能拉箱子,因此如果箱子被推到一个角上(如图2)那么箱子就不能再被移动了,如果箱子被推到一面墙上,那么箱子只能沿着墙移动.

现在给定房间的结构,箱子的位置,搬运工的位置和箱子要被推去的位置,请你计算出搬运工至少要推动箱子多少格.

bubuko.com,布布扣

 

Input
输入数据的第一行是一个整数T(1<=T<=20),代表测试数据的数量.然后是T组测试数据,每组测试数据的第一行是两个正整数M,N(2&lt;=M,N<=7),代表房间的大小,然后是一个M行N列的矩阵,代表房间的布局,其中0代表空的地板,1代表墙,2代表箱子的起始位置,3代表箱子要被推去的位置,4代表搬运工的起始位置.
 

Output
对于每组测试数据,输出搬运工最少需要推动箱子多少格才能帮箱子推到指定位置,如果不能推到指定位置则输出-1.
 

Sample Input
1 5 5 0 3 0 0 0 1 0 1 4 0 0 0 1 0 0 1 0 2 0 0 0 0 0 0 0
 

Sample Output
4 因为只要求一个箱子到目的地的最短步数 所以只要考虑如下几点即可: 1:一箱子作为主体 对其BFS寻找最短路 2:每次箱子移动前都要判断人能否到达箱子后面 3:人不能经过箱子 4:箱子可能重复经过同一点 代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define qq 9
using namespace std;
int map[qq][qq];
int vis[qq][qq][4];               //箱子的访问数组 必须开三维 因为可能经过同一坐标
int dis[qq][qq];                  //人的访问数组
int fx[4][2]= {1,0,0,1,0,-1,-1,0};
struct node
{
    int x,y,x1,y1,step;
};
int m,n;
int sx,sy,sx1,sy1;
int tx1,ty1,tt;
bool inmap(int a,int b)
{
    if(a<1||a>m||b<1||b>n||map[a][b]==1)
        return false;
    return true;
}
void dfs(int xx,int yy)            //人能否到达箱子后面
{
    if(xx==tx1&&yy==ty1)
    {
        tt=1;
        return ;
    }
    if(tt==1)
        return;
    int tx,ty;
    for(int i=0; i<4; i++)
    {
       tx=xx+fx[i][0];
       ty=yy+fx[i][1];
       if(tx<1||ty<1||tx>m||ty>n||map[tx][ty]==1||dis[tx][ty]==1)
        continue;
       dis[tx][ty]=1;
       dfs(tx,ty);
       dis[tx][ty]=0;
    }
}
void bfs()
{
    queue<node>q;
    node now,next;
    memset(vis,0,sizeof(vis));
    memset(dis,0,sizeof(dis));
    now.x=sx,now.y=sy;
    now.x1=sx1,now.y1=sy1;
    now.step=0;
    q.push(now);
    while(!q.empty())
    {
        now=q.front();
        q.pop();
        if(map[now.x][now.y]==3)
        {
            cout<<now.step<<endl;
            return;
        }
        for(int i=0; i<4; i++)
        {
            next.x=now.x+fx[i][0];
            next.y=now.y+fx[i][1];
            tx1=now.x-fx[i][0];
            ty1=now.y-fx[i][1];
            next.step=now.step+1;
            if(inmap(next.x,next.y)&&inmap(tx1,ty1)&&map[next.x][next.y]!=1&&vis[next.x][next.y][i]==0)
            {


                memset(dis,0,sizeof(dis));
                tt=0;
                dis[now.x1][now.y1]=1;
                dis[now.x][now.y]=1;
                dfs(now.x1,now.y1);                     //重要 人不能穿过箱子
                dis[now.x1][now.y1]=0;
                dis[now.x][now.y]=0;
                if(tt==1)
                {
                    vis[next.x][next.y][i]=1;
                    next.x1=tx1;
                    next.y1=ty1;
                    q.push(next);
                }
            }
        }
    }
    cout<<-1<<endl;
    return;
}
int main()
{
    int t,i,j;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&m,&n);
        for(i=1; i<=m; i++)
            for(j=1; j<=n; j++)
            {
                scanf("%d",&map[i][j]);
                if(map[i][j]==2)
                    sx=i,sy=j;
                if(map[i][j]==4)
                    sx1=i,sy1=j;
            }
        bfs();
    }
    return 0;
}


HDU 1254 (经典游戏)推箱子 BFS+dfs,布布扣,bubuko.com

HDU 1254 (经典游戏)推箱子 BFS+dfs

标签:c++

原文地址:http://blog.csdn.net/axuan_k/article/details/38404057

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!