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

题目链接: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. memcached参数解释及常用命令

    一.执行 memcached -h 会显示所有的参数项,对应的中文解释如下: -p <num>      监听的TCP端口(默认: 11211) -U <num>      监 ...

  2. Flask入门笔记(一)

    一.程序的基本结构 1.1 最简单的Flask程序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #coding=utf-8 # 初始化 from flask import Fla ...

  3. win32 htmlayout点击按钮创建新窗口,以及按钮图片样式

    最近在做一个C++ win32的桌面图形程序,我不是C++程序员,做这个只是因为最近没什么java的活. windows api,之前接触的时候,还是大学,那时用这个开发打飞机游戏纯粹是娱乐.现在基本 ...

  4. oracle索引(转)

    引,索引的建立.修改.删除 2007-10-05 13:29 来源: 作者: 网友评论 0 条 浏览次数 2986 索引索引是关系数据库中用于存放每一条记录的一种对象,主要目的是加快数据的读取速度和完 ...

  5. Java日期格式化方法

    首先获取当前系统时间的方法有两种:第一种可以用currentTimeMillis()方法获取,它其实产生的是一个当前的毫秒数,这个毫秒是自1970年1月1日0时起至现在的毫秒数,类型是long 型,可 ...

  6. String 类的实现(3)引用计数实现String类

    我们知道在C++中动态开辟空间时是用字符new和delete的.其中使用new test[N]方式开辟空间时实际上是开辟了(N*sizeof(test)+4)字节的空间.如图示其中保存N的值主要用于析 ...

  7. 老李推荐:第8章5节《MonkeyRunner源码剖析》MonkeyRunner启动运行过程-运行测试脚本

    老李推荐:第8章5节<MonkeyRunner源码剖析>MonkeyRunner启动运行过程-运行测试脚本   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化 ...

  8. 1.熟悉Java基本类库系列 - 目录

    写这个系列是想让自己多熟悉熟悉Java的基本类库,忘记的时候可以在这里看看之前写过的例子,这样就可以很快的回忆起来如何使用了. 这样就可以很节省时间了. ======= 下面是传送门啦 ======= ...

  9. WebApp框架

    我所知道的webapp开发框架,欢迎补充, Framework7包含ios和material两种主题风格并且有vue版和react版, vue发现一个vue-material, react有一款mat ...

  10. 学Java,是自学还是去培训班学习?

    现在正在读在校的最后一个学年,想毕业后从事编程,但是感觉自己技术太差,应该是培训呢?还是去找实习?亦或是有更好的途径? 对于 Android 目前的行业趋势,不知道自己该不该坚持?还是转其他行业? 已 ...