搜索 [HDU 1254] 推箱子

推箱子

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 5343    Accepted Submission(s): 1503

Problem Description

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

Input

输入数据的第一行是一个整数T(1<=T<=20),代表测试数据的数量.然后是T组测试数据,每组测试数据的第一行是两个正整数M,N(2<=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

搜索水题、
百度了下,目测网上基本都是搜索套搜索。。。。。

代码可能会有错、没怎么检查就水过了。

应该容易懂、不注释了 - -

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
#define INF 0x7ffffff
#define N 8

struct node
{
    int px,py;
    int bx,by;
    int step;
};

int ans;
int flag;
int n,m;
int px,py;
int bx,by;
int mpt[N][N];
int vis1[N][N];
int vis2[N][N][N][N];
int dir[4][2]={0,-1,0,1,-1,0,1,0};

bool judge(int x,int y)
{
    if(x>=1 && x<=n && y>=1 && y<=m && mpt[x][y]!=1) return 1;
    return 0;
}
void bfs()
{
    queue<node> q;
    node now,next;
    now.bx=bx;
    now.by=by;
    now.px=px;
    now.py=py;
    now.step=0;
    vis2[now.bx][now.by][now.px][now.py]=1;
    q.push(now);
    while(!q.empty())
    {
        now=q.front();
        q.pop();
        if(mpt[now.bx][now.by]==3)
        {
            ans=min(ans,now.step);
            return;
        }
        for(int i=0;i<4;i++)
        {
            next=now;
            next.px+=dir[i][0];
            next.py+=dir[i][1];
            if(!judge(next.px,next.py)) continue;
            if(next.bx==next.px && next.by==next.py)
            {
                next.step++;
                next.bx+=dir[i][0];
                next.by+=dir[i][1];
                if(!judge(next.bx,next.by)) continue;
            }
            if(!vis2[next.bx][next.by][next.px][next.py])
            {
                vis2[next.bx][next.by][next.px][next.py]=1;
                q.push(next);
            }
        }
    }
}
void dfs(int x,int y)
{
    if(mpt[x][y]==4)
    {
        flag=1;
        return;
    }
    if(flag) return;
    for(int i=0;i<4;i++)
    {
        int tx=x+dir[i][0];
        int ty=y+dir[i][1];
        if(judge(tx,ty) && mpt[tx][ty]!=2 && !vis1[tx][ty])
        {
            vis1[tx][ty]=1;
            dfs(tx,ty);
            vis1[tx][ty]=0;
        }
    }
}
int main()
{
    int T,i,j;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)
            {
                scanf("%d",&mpt[i][j]);
                if(mpt[i][j]==2)
                {
                    bx=i;
                    by=j;
                }
            }
        }
        ans=INF;
        for(i=0;i<4;i++)
        {
            px=bx+dir[i][0];
            py=by+dir[i][1];
            if(judge(px,py))
            {
                flag=0;
                memset(vis1,0,sizeof(vis1));
                dfs(px,py);
                if(flag)
                {
                    memset(vis2,0,sizeof(vis2));
                    bfs();
                }
            }
        }
        if(ans==INF)
            cout<<-1<<endl;
        else
            cout<<ans<<endl;
    }
    return 0;
}
时间: 2024-11-03 16:14:47

搜索 [HDU 1254] 推箱子的相关文章

HDU 1254——推箱子

这题跟 hdu 1734 push box 是一样的,只不过这题推的是一个箱子,另外求的是箱子被推了多少次,那么只要在箱子被推的时候 次数才加1,然后使用优先队列就ok了 写了1734就会觉得这题很水啦  HDU1734题解 网上主流的都是bfs+bfs,或者是bfs+dfs <span style="font-size:18px;">#include<iostream> #include<cstring> #include<algorithm

HDU 1254 推箱子

一个很有意思的 BFS+DFS.附 数据. 本来今天的任务是多重背包,结果为了帮别人找WA点,自己也坑在这道题上了. 最后想了一组自己都没过的数据-发现想法都不对-果断换思路了. 正确思路是以箱子为起点做BFS找最短.每次移动的时候DFS判断人能不能移动到箱子的后面. 开始就我写一个BFS,什么数据都过了.这组过不了 1 7 4 0 0 0 0 0 0 1 0 0 2 0 3 1 4 1 0 1 0 1 0 1 0 1 0 1 0 0 0 实际上答案是2. 我写的是总步数最短时,箱子的最短步数.

hdu - 1254 推箱子 (bfs+bfs)

http://acm.hdu.edu.cn/showproblem.php?pid=1254 题目意思很简单,只要思路对就好. 首先考虑搬运工能否到达推箱子的那个点,这个可以根据箱子前进方向得出搬运工需要到达的目的地,用另一个bfs判断,然后就类似两个点的bfs那样用一个数组标记状态, 需要注意箱子在边上的情况. 1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 using namespace std;

HDU 1254 推箱子 BFS

囧,一开始没有管人的情况,只看箱子,果然SB了. #include <cstdio> #include <cstring> #include <iostream> #include <map> #include <set> #include <vector> #include <string> #include <queue> #include <deque> #include <bitset

poj 1254 推箱子

New~ 欢迎“热爱编程”的高考少年——报考杭州电子科技大学计算机学院 关于2015年杭电ACM暑期集训队的选拔 欢迎参加: 浙江杭电{安控杯}Hackthon 推箱子 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6027    Accepted Submission(s): 1721 Problem Description 推箱子

hdu 1254(推箱子游戏bfs+状态标记)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1254 推箱子 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 5181    Accepted Submission(s): 1439 Problem Description 推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N

hdu 1254(两个BFS) 推箱子

http://acm.hdu.edu.cn/showproblem.php?pid=1254 首先,要判断人是不是可以从4到达箱子的位置2,而且不止判断一次,因为推动箱子一步后,人的位置也会改变,所以每次移动箱子前都要判断 所以这里要用两个搜索,当每朝着一个方向移动一步箱子的时候,就需要判断 从 此刻的 人位置能不能到达箱子反方向的那个位置(人只能推箱子, 不能拉什么的)  注意人在移动的时候箱子对于人来说也算障碍物,这里需要开一个hash1的四维数组记录走过的位置,不然会死循环超时间 这个记录

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

Problem Description 推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N的房间里有一个箱子和一个搬运工,搬运工的工作就是把箱子推到指定的位置,注意,搬运工只能推箱子而不能拉箱子,因此如果箱子被推到一个角上(如图2)那么箱子就不能再被移动了,如果箱子被推到一面墙上,那么箱子只能沿着墙移动. 现在给定房间的结构,箱子的位置,搬运工的位置和箱子要被推去的位置,请你计算出搬运工至少要推动箱子多少格. Input 输入数据的第一行是一个整数T(1<=T<=20),代表测试

推箱子(嵌套搜索,bfs中有dfs)

推箱子 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 6416    Accepted Submission(s): 1834 Problem Description 推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N的房间里有一个箱子和一个搬运工,搬运工的工作就是把箱子推到指定的位置,注意,搬运工只能推箱子而不能拉箱子,