hdu 1732 Push Box(bfs)_zthgreat的博客-程序员宝宝

技术标签: 【搜索、递推、树】  bfs  

Problem Description
Push Box is a classic puzzle game. This game play in a grid, there are five types of block in it, the player, the box, the hole, empty place, and the wall. In every step, player can move up, down, left, or right, if the target place is empty. Moreover, if a box in the target place, and the next place in that direction is empty, player can move to the target place, and then push the box to the next place. Remember, both of the player and boxes can't move out of the grid, or you may assume that there is a wall suround the whole grid. The objective of this game is to push every box to a hole. Now, your problem is to find the strategy to achieve the goal with shortest steps, supposed there are exactly three boxes.
 

Input
The input consists of several test cases. Each test case start with a line containing two number, n, m(1 < n, m ≤ 8), the rows and the columns of grid. Then n lines follow, each contain exact m characters, representing the type of block in it. (for empty place, X for player, * for box, # for wall, @ for hole). Each case contain exactly one X, three *, and three @. The input end with EOF.
 

Output
You have to print the length of shortest strategy in a single line for each case. (-1 if no such strategy)
 

Sample Input
  
  
   
4 4 .... ..*@ ..*@ .X*@ 6 6 ...#@. @..*.. #*##.. ..##*# ..X... .@#...
 

Sample Output
  
  
   
7 11

题意:类似推箱子游戏,三个箱子,三个目的地,求出人把三个箱子都推到目的地的最小步数,若没法完成就输出-1。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <queue>
#define INF 100000000
using namespace std;
int n,m;
char map[9][9];
bool vis[8][8][8][8][8][8][8][8];
bool aim[8][8];
int dir[4][2]={
   {-1,0},{0,1},{1,0},{0,-1}};
struct point
{
    int x;
    int y;

};
struct node
{
    point p[4];
    int step;
};
node s,e;
bool ok(node &a)  //箱子是否全部进洞
{
    for (int i=1; i<=3; i++)
    {
        if(!aim[a.p[i].x][a.p[i].y])
            return false;
    }
    return true;
}
int bfs()
{
    memset(vis, false, sizeof(vis));
    memset(aim, false, sizeof(aim));
    for (int i=0; i<3; i++)
        aim[e.p[i].x][e.p[i].y]=true;  //目标状态
    
    queue<node>q;
    node temp;
    q.push(s);
    vis[s.p[0].x][s.p[0].y][s.p[1].x][s.p[1].y][s.p[2].x][s.p[2].y][s.p[3].x][s.p[3].y]=true;
    while (!q.empty())
    {
        s=q.front();
        q.pop();
        if(ok(s))
            return s.step;
        for (int i=0; i<4; i++)
        {
            temp=s;
            temp.p[0].x+=dir[i][0]; //人移动
            temp.p[0].y+=dir[i][1];
            int x=temp.p[0].x;
            int y=temp.p[0].y;
            if(x<0 || x>=n || y<0 || y>=m || map[x][y]=='#')
                continue;
            int j;
            //判断人是否遇到箱子
            for (j=1; j<=3; j++)
            {
                if(x==temp.p[j].x && y==temp.p[j].y)
                {
                    break;
                }
            }
            if(j==4) //人未遇到箱子
            {
                if(!vis[x][y][temp.p[1].x][temp.p[1].y][temp.p[2].x][temp.p[2].y][temp.p[3].x][temp.p[3].y])
                {
                    temp.step++;
                    vis[x][y][temp.p[1].x][temp.p[1].y][temp.p[2].x][temp.p[2].y][temp.p[3].x][temp.p[3].y]=true;
                    q.push(temp);
                }
            }
            else //遇到箱子,则移动箱子
            {
                //箱子移动后的坐标
                x+=dir[i][0];
                y+=dir[i][1];
                if(x<0 || x>=n || y<0 || y>=m || map[x][y]=='#')
                    continue;
                int k;
                for (k=1; k<=3; k++) //判断是否有其它箱子阻挡
                {
                    if(x==temp.p[k].x && y==temp.p[k].y)
                        break;
                }
                if(k==4) //没有其它箱子阻挡
                {
                    temp.p[j].x=x;
                    temp.p[j].y=y;
                    if(!vis[temp.p[0].x][temp.p[0].y][temp.p[1].x][temp.p[1].y][temp.p[2].x][temp.p[2].y][temp.p[3].x][temp.p[3].y])
                    {
                        temp.step++;
                        vis[temp.p[0].x][temp.p[0].y][temp.p[1].x][temp.p[1].y][temp.p[2].x][temp.p[2].y][temp.p[3].x][temp.p[3].y]=true;
                        q.push(temp);
                    }
                }
            }
        }
    }
    return -1;
}
int main()
{
    int cnt,cnt2;
    while (scanf("%d%d",&n,&m)!=EOF)
    {
        cnt=0;
        cnt2=0;
        for (int i=0; i<n; i++)
        {
            scanf("%s",map[i]);
            for (int j=0; j<m; j++)
            {
                if(map[i][j]=='X')
                {
                    s.p[0].x=i;
                    s.p[0].y=j;
                }
                else if(map[i][j]=='*')
                {
                    s.p[++cnt].x=i;
                    s.p[cnt].y=j;
                }
                else if(map[i][j]=='@')
                {
                    e.p[cnt2].x=i;
                    e.p[cnt2++].y=j;
                }
                if(map[i][j]!='#')
                    map[i][j]='.';
            }
        }
        s.step=0;
        printf("%d\n",bfs());
    }
    return 0;
}


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u014634338/article/details/47952863

智能推荐

AD20学习笔记_朽木白露的博客-程序员宝宝

一般使用流程https://blog.csdn.net/BerryNard/article/details/100147638AD20如何导入库文件http://bbs.elecfans.com/jishu_1883798_1_1.html

os任务调度实现原理_os 任务调度_cheng3100的博客-程序员宝宝

文章目录为什么要做任务调度-why任务调度需要做什么?-what怎样实现任务调度?-how为什么要做任务调度-why操作系统中最为显著的特性就是任务调度,任务调度主要来自于以下几种需求:程序并发(multiprogram)任务间同步、消息传递实时性能要求其中第一点程序并发很好理解,对于一般意义的单核硬件平台而言,任何特定时间实际只能有一个机器指令在执行(实际上对于现代cpu不准...

Web笔记-通过版本号控制客户端浏览器中的缓存_通过版本号解决缓存_IT1995的博客-程序员宝宝

这里举个例子:通过Python管理静态资源。但有时候,js或者css更新了,浏览器不知道,还使用缓存的情况。如下所示:通过在url中带个?这种方式,使得浏览器去获取新的资源看下根请求下相关链接:后面这一串是根据时间产生的随机数。如果是开发环境,我们通过这种方式,使得客户端浏览器都获取到新的资源。生产环境,通过文件进行指定版本:相关的python...

安装完Hadoop之后,命令行输入hadoop或hdfs却找不到命令的解决方法_weixin_30481087的博客-程序员宝宝

大多数原因是没有配置环境变量解决方法1. cd /etc/profile2. 把这三条加到proflie文件的最后1 export JAVA_HOME=XXXX(在安装了jdk的前提下,echo $JAVA_HOME可以查看得到)2 export HADOOP_HOME=XXX(hadoop的安装路径)3 export PATH=.:$HADOOP_HOME/bin:$...

从Linux内核源码到操作系统_如何基于linux内核开发自己的操作系统_巭犇的博客-程序员宝宝

Linux源码只有运行起来才能成为操作系统,否则她只能静静的躺在存储介质上沉睡,本文就讲解如何将这个睡美人唤醒,唤醒后给他穿上旗袍她就成为RedHat,给她换上包臀裙她就成为SUSE,再或者给她换上超短裙,她就成为Ubuntu,总之就是你可以按照自己的想象,随意打扮这个小姑娘,当然我们也可让她裸奔。没有编译过内核的朋友,可以查看我之前写过的一篇文章,本文在此基础之上,将唤醒这个沉睡的美人。..................

奇偶校验c语言ascii,奇偶校验(parity check)_湛蓝色的迷惘的博客-程序员宝宝

parity check 奇偶校验[N] a check made of computer data to ensure that the total number of bits of value 1 (or 0) in each unit of information remains odd or even after transfer between a peripheral device ...

随便推点

[深入浅出C语言]理解取整、取余和取模_linux c取整函数_Linux服务器开发的博客-程序员宝宝

给出一个定义: 如果a和d是两个自然数,d非零,可以证明存在两个唯一的整数 q 和 r,满足 a = q*d + r 且0 ≤ r < d。其中,q被称为商,r 被称为余数,取模运算求取的就是这个余数r。return 0;}结果显而易见会是1,那如果改成下面这样结果又会如何?int main(){//改成负数了int b = 3;return 0;}2>>>

机器学习-白板推导-系列(八)笔记:指数族分布/充分统计量/对数配分函数/最大熵_指数分布的充分统计量_流动的风与雪的博客-程序员宝宝

本博客为(系列八)的笔记,对应的视频是:【(系列八) 指数族分布1-背景】、【(系列八) 指数族分布2-背景续】、【(系列八) 指数族分布3-高斯分布的指数族形式】、【(系列八) 指数族分布4-对数配分函数与充分统计量】、【(系列八) 指数族分布5-极大似然估计与充分统计量】、【(系列八) 指数族分布6-最大熵角度(1)】、【(系列八) 指数族分布7-最大熵角度(2)】。

解决Python3.7根目录中没有Scripts文件夹_python的scripts在哪_盼盼大魔王的博客-程序员宝宝

一般会报错'pip' 不是内部或外部命令,也不是可运行的程序或批处理文件。1、打开命令行输入python -m ensurepip2、查看Python根目录下的Scripts文件夹中是否有pip相关文件3、切换到Scripts文件夹中,输入命令:easy_install.exe pip4、将Scripts目录添加到环境变量...

吴军:站在浪潮之巅,5G 和 IoT 才是未来 10 年的浪潮 | 人物志_csdn物联网开发的博客-程序员宝宝

作者 | 胡巍巍出品 | CSDN(ID:CSDNnews)7 月 12 日,在北京怀柔团建的笔者,在山窝里接通了大洋彼岸的吴军老师的电话。吴军老师的经历,横跨产学研。他...

如何实现局域网内两台电脑资源共享?_cmd如何实现局域网上两台设备的互联_wangqingsong575的博客-程序员宝宝

1.更改不同的计算机名,设置相同的工作组! 2.我的电脑右键-管理-计算机管理-本地用户和组-用户:更改管理员用户名 3.手动设置IP,将ip设置在同一个网段,子网掩码和DNS解析相同 (路由开dhcp可略) 4.如何设置DNS解析:首先你可以使用自动获取,然后在开始-运行里面输入cmd后回车,在命令里面输入ipconfig/all后回车 5.运行里输入services.msc回车打开服务 共享的

log4j 多classloader重复加载配置问题解决_ignoretcl_茜茜770的博客-程序员宝宝

log4j:ERROR A "org.apache.log4j.xml.DOMConfigurator" object is not assignable to a "org.apache.log4j.spi.Configurator" variable.log4j:ERROR The class "org.apache.log4j.spi.Configurator" was loaded b

推荐文章

热门文章

相关标签