我写的第一道感觉比较难的搜索

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1254

首先要推箱子的话要满足人能够在箱子旁边,而且人的对面也是可通的。

我的思路:

先判断箱子周围的空地(即可能能被人推到的格子),然后判断人是否能够达到即将推箱子的位置,在这里我用BFS嵌套DFS,其中BFS用优先权队列进行维护,每次取步数最少的当前箱子的位置,然后对于当前箱子可以到达的位置来说,DFS人,判断人能否到达推箱子的位置。

在这里,重要的一点是,对于一个当前的箱子,可以从不同的方向推,所以我用visit[x][y][z][k]判断对于当前的x,y格子里的箱子来说,是否已经被在z,k格子里的人推过,推过为1。

代码运行时间0MS

代码实现如下:

#include<cstdlib>
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<fstream> using namespace std;
class node
{
public:
int x;
int y;
int step;
int people_x;
int people_y;
friend bool operator <(node a,node b)
{
return a.step>b.step;
}
}cur,next;
priority_queue<node>q;
int d[4][2]={1,0,-1,0,0,1,0,-1};
int visit[10][10][10][10];
int visit2[10][10];
int map[10][10];
bool flag;
int m,n;
int start1_x,start1_y;
int start2_x,start2_y;
int end_x,end_y; void init()
{
memset(visit,0,sizeof(visit));
memset(map,1,sizeof(map));
memset(visit2,0,sizeof(visit2));
flag=0; }
int flag1=0;
int cur_x,cur_y;
bool dfs(int x,int y,int cur_x, int cur_y ,int people_x,int people_y)
{
visit2[x][y]=1; if(x==people_x&&y==people_y) {flag1=1;return true;}
if(flag1==0)
for(int i=0;i<4;i++)
{
int xx=x+d[i][0];
int yy=y+d[i][1];
if(xx>m||xx<1||yy>n||yy<1||map[xx][yy]==1||visit2[xx][yy]||(xx==cur_x&&yy==cur_y)) continue; dfs(xx,yy,cur_x,cur_y,people_x,people_y);
if(flag1) return true;
}
return false; }
void bfs()
{
while(!q.empty())
{
cur=q.top();
q.pop();
if(cur.x==end_x&&cur.y==end_y)
{
cout<<cur.step<<endl;
flag=1;
break;
}
for(int i=0;i<4;i++)
{
memset(visit2,0,sizeof(visit2));
flag1=0;
int x=cur.x+d[i][0];
int y=cur.y+d[i][1]; if(x>m||x<1||y>n||y<1||map[x][y]==1) continue;
next.x=x;next.y=y;
next.people_x=cur.x;
next.people_y=cur.y;
next.step=cur.step+1;
if(i==0)
if(map[cur.x-1][cur.y]!=1&&dfs(cur.x-1,cur.y,cur.x,cur.y,cur.people_x,cur.people_y)&&visit[x][y][cur.x-1][cur.y]==0)
{
visit[x][y][cur.x-1][cur.y]=1;
q.push(next);
}
if(i==1)
if(map[cur.x+1][cur.y]!=1&&dfs(cur.x+1,cur.y,cur.x,cur.y,cur.people_x,cur.people_y)&&visit[x][y][cur.x+1][cur.y]==0)
{
visit[x][y][cur.x+1][cur.y]=1;
q.push(next);
}
if(i==2)
if(map[cur.x][cur.y-1]!=1&&dfs(cur.x,cur.y-1,cur.x,cur.y,cur.people_x,cur.people_y)&&visit[x][y][cur.x][cur.y-1]==0)
{
visit[x][y][cur.x][cur.y-1]=1;
q.push(next);
}
if(i==3)
if(map[cur.x][cur.y+1]!=1&&dfs(cur.x,cur.y+1,cur.x,cur.y,cur.people_x,cur.people_y)&&visit[x][y][cur.x][cur.y+1]==0)
{
visit[x][y][cur.x][cur.y+1]=1;
q.push(next);
} }
}
}
int main()
{
int t;
cin>>t;
while(t--)
{
init();
while(!q.empty()) q.pop();
scanf("%d%d",&m,&n); for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
{
scanf("%d",&map[i][j]);
if(map[i][j]==2)
{
start1_x=i;
start1_y=j;
}
if(map[i][j]==3)
{
end_x=i;
end_y=j;
}
if(map[i][j]==4)
{
start2_x=i;
start2_y=j;
}
}
cur.x=start1_x;
cur.y=start1_y;
cur.step=0;
cur.people_x=start2_x;
cur.people_y=start2_y; q.push(cur);
bfs();
if(flag==0) cout<<"-1"<<endl;
}
return 0;
}

  

hdu 1254 推箱子(搜索)的更多相关文章

  1. HDU 1254 推箱子(BFS加优先队列)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1254 推箱子 Time Limit: 2000/1000 MS (Java/Others)    Me ...

  2. hdu 1254 推箱子(嵌套搜索,bfs中有dfs)

    推箱子 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...

  3. HDU 1254 推箱子 BFS

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1254 题目分析: 做这道题,感觉挺简单的,做着做着就错了20次, 我也是醉了, WA到吐的节奏啊! 思 ...

  4. hdu - 1254 推箱子 (bfs+bfs)

    http://acm.hdu.edu.cn/showproblem.php?pid=1254 题目意思很简单,只要思路对就好. 首先考虑搬运工能否到达推箱子的那个点,这个可以根据箱子前进方向得出搬运工 ...

  5. [HDU 1254] 推箱子

    推箱子 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

  6. hdu.1254.推箱子(bfs + 优先队列)

    推箱子 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

  7. HDU 1254 推箱子(BFS)

    Problem Description 推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N的房间里有一个箱子和一个搬运工,搬运工的工作就是把箱子推到指定的位置,注意,搬运工只能推箱子而不 ...

  8. hdu 1254 推箱子(双重bfs)

    题目链接 Problem Description 推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N的房间里有一个箱子和一个搬运工,搬运工的工作就是把箱子推到指定的位置,注意,搬运工只能 ...

  9. HDU 1254 推箱子游戏(搞了一下午。。。)

    中文题目:http://acm.hdu.edu.cn/showproblem.php?pid=1254 一开始常规的人用来做主导,想着想着不对劲,其实是箱子为主导,人只是箱子能否推进的一个判断. 可以 ...

随机推荐

  1. Fireworks快捷键大全和ps查看切图的坐标颜色

    记住后方便了许多

  2. MySQL基础入门-第一课 新建数据库(linux版本)

    MySQL linux 登录MySQL sudo ),name ),phone )  );  # 或者  ),name ),phone ));  数据类型 数据类型 大小(字节) 用途 格式 INT ...

  3. WKWebView代理方法解析

    一.前言 上一篇文章已经对WKWebView做了一个简单的介绍,主要对它的一些方法和属性做了一个简单的介绍,今天看一下WKWebView的两个协议:WKNavigationDelegate 和 WKU ...

  4. 模块“XXX.dll”加载失败

    具体问题:模块“XXX.dll”加载失败 请确保该二进制存储在指定的路径中,或者调试它以检查该二进制或相关的.DLL文件是否有问题  找不到指定的模块. 1.在安装C++软件的时候,有时候安装失败提示 ...

  5. 一步步教你使用rem适配不同屏幕的移动设备

    1.先说说几个前端常用的几个单位的概论: 1.px (pixel,像素):是一个虚拟长度单位,是计算机系统的数字化图像长度单位,如果px要换算成物理长度,需要指定精度DPI(Dots Per Inch ...

  6. Java并发编程:JDK中的阻塞队列

    上次我们讲了一些常用的4个阻塞队列,但是在JDK中还提供了其他的一些阻塞队列.这篇文章将全面介绍一下JDK中的所有阻塞队列,并比较他们的区别. JDK7提供了7个阻塞队列.分别是 ArrayBlock ...

  7. MyEclipse常见错误

    1.Could not create the view: An unexpected exception was thrown java.lang.NullPointerException     a ...

  8. jmeter参数化随机取值实现

    jmeter能用来做参数化的组件有几个,但是都没有随机取值的功能,遇到随机取值的需求怎么办呢? 突发奇想,可以用函数__CSVRead()来实现: __CSVRead() CSV file to ge ...

  9. SIM9001GSM模块教程

    博主最近在做一个项目,用到了GSM模块,博主不是什么单片机大神,只是感觉某宝附带的资料太水,所以上传一些自己写的程序和经验,供需要的人参考 1,拨打电话 /********************** ...

  10. HibernateTemplate的使用

    HibernateTemplate 提供了非常多的常用方法来完成基本的操作,比如增加.删除.修改及查询等操作,Spring 2.0 更增加对命名 SQL 查询的支持,也增加对分页的支持.大部分情况下, ...