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

题目链接: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. CSS.03 -- 浏览器行高、字体;盒子模型--边框、内边距、外边距

    如果此时你也在自学中,请使用 FireWorks CS6 进行切图测距等,百度一下吧~ Fireworks的基本使用 新建文件   ctrl+n 打开文件  ctrl+o 调出和隐藏标尺 ctrl+r ...

  2. CDMA sid, nid, bid 含义解释

    copyright@ celldb.cc SID 是系统识别码,每个地级市只有一个sid,是唯一的. NID是网络识别码,由各本地网管理,也就是由地级分公司分配.每个地级市可能有1到3个nid. BI ...

  3. 一行命令创建 http-server

    一行命令启动http-server总结:1. python2.xpython2 -m SimpleHTTPServer 8000 2. python3.xpython -m http.server 8 ...

  4. Python快速入门(4)

    输入输出: open() read() readine() readlines() write() pickle模块可以做序列化操作,持久保持对象的信息. 我们可以很容易的读写文件中的字符串.数值就要 ...

  5. iOS性能之其他

    本篇文章是个引用,因为这些技术我都只是研究过,但是并没有在项目中使用,也没有深入研究,所以只能当做一个笔记了 网络请求 现在大多数的网络请求都是使用的json格式(相信没有APP再使用XML格式了吧) ...

  6. unity插件开发——AssetDatabase

    AssetDatebase也是一个静态类,他的作用是管理整个工程的所有文件(一般成为“资产”).直观地说就是管理整个project窗口中的所有内容,比如,你可以增加.删除.修改文件等等. 这里有几个常 ...

  7. zabbix 监控 tomcat jmx

    zabbix_server: zabbix_server.conf : # Add JavaGateway=127.0.0.1 JavaGatewayPort=10052 StartJavaPolle ...

  8. Unix环境编程基础下

    Unix出错处理 当UNIX系统的函数出错时,通常会返回一个负值.我们判断函数的返回值小于0表示出错了,注意我们并不知道为什么出错.例如我们open一个文件,返回值-1表示打开失败,但是为什么打开失败 ...

  9. jQuery习题

    1.在div元素中,包含了一个<span>元素,通过has选择器获取<div>元素中的<span>元素的语法是? 答:$("div:has(span)&q ...

  10. DC平衡双向控制串行器 转接IC GM8913:LVTTL转FPD-LINK III芯片

    1 概述     GM8913型DC平衡双向控制串行器,其主要功能是实现将10或12位并行控制信号和一路时钟信号串行为一路2.8Gbps高速串行数据:同时接收低速通道信号实现模式配对的功能.芯片内部集 ...