来一发搜索。数据量比较小,这么玩儿都能ac。搞个优先队列。
先扫描从起点可以到达箱子的上下左右中哪些位置,并针对这些位置进行bfs。
所谓推,就是箱子和人同向移动一个单位。bfs的时候注意一些限制条件就好了。

 /* 1254 */
#include <iostream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000") #define sti set<int>
#define stpii set<pair<int, int> >
#define mpii map<int,int>
#define vi vector<int>
#define pii pair<int,int>
#define vpii vector<pair<int,int> >
#define rep(i, a, n) for (int i=a;i<n;++i)
#define per(i, a, n) for (int i=n-1;i>=a;--i)
#define clr clear
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1 const int maxn = ;
int M[maxn][maxn];
bool reach[maxn][maxn];
bool visit[maxn][maxn][maxn][maxn];
int dir[][] = {
-,, ,, ,-, ,
};
int gx, gy, bx, by, hx, hy;
int n, m;
int ans; bool judge(int x, int y) {
return x< || x>=n || y< || y>=m;
} void bfs_human() {
queue<pii> Q;
pii p;
int x, y; memset(reach, false, sizeof(reach));
reach[hx][hy] = true;
Q.push(mp(hx, hy)); while (!Q.empty()) {
p = Q.front();
Q.pop();
rep(i, , ) {
x = p.fir + dir[i][];
y = p.sec + dir[i][];
if (judge(x, y) || M[x][y]!= || reach[x][y])
continue;
reach[x][y] = true;
Q.push(mp(x, y));
}
}
} typedef struct node_t {
int hx, hy;
int bx, by;
int bn; node_t() {} node_t(int hx, int hy, int bx, int by, int bn):
hx(hx), hy(hy), bx(bx), by(by), bn(bn) {} friend bool operator< (const node_t& a, const node_t& b) {
return a.bn > b.bn;
} void print() {
printf("hx=%d, hy=%d, bx=%d, by=%d, bn=%d\n", hx,hy,bx,by,bn);
} } node_t; // #define DEBUG
int bfs(int hx, int hy) {
priority_queue<node_t> Q;
node_t d(hx, hy, bx, by, ), nd; memset(visit, false, sizeof(visit));
visit[bx][by][hx][hy] = true;
Q.push(d); while (!Q.empty()) {
nd = Q.top();
Q.pop();
#ifdef DEBUG
nd.print();
if (nd.hx== && nd.hy== && nd.bx== && nd.by==) {
puts("here");
}
#endif
rep(i, , ) {
d.hx = nd.hx + dir[i][];
d.hy = nd.hy + dir[i][];
if (judge(d.hx, d.hy) || M[d.hx][d.hy]==)
continue; // check whether is box
if (d.hx==nd.bx && d.hy==nd.by) {
d.bx = nd.bx + dir[i][];
d.by = nd.by + dir[i][];
if (judge(d.bx, d.by) || M[d.bx][d.by]==)
continue;
d.bn = nd.bn + ;
} else {
d.bx = nd.bx;
d.by = nd.by;
d.bn = nd.bn;
} if (visit[d.bx][d.by][d.hx][d.hy])
continue; visit[d.bx][d.by][d.hx][d.hy] = true;
if (d.bx==gx && d.by==gy)
return d.bn; #ifdef DEBUG
nd.print();
if (d.hx== && d.hy== && d.bx== && d.by==) {
puts("there");
}
#endif
Q.push(d);
}
} return INT_MAX;
} void solve() {
int x, y, tmp; ans = INT_MAX; bfs_human();
rep(i, , ) {
x = bx + dir[i][];
y = by + dir[i][];
if (judge(x, y) || M[x][y]== || !reach[x][y])
continue;
tmp = bfs(x, y);
ans = min(tmp, ans);
} ans = ans==INT_MAX ? -:ans;
printf("%d\n", ans);
} int main() {
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif int t; scanf("%d", &t);
while (t--) {
scanf("%d %d", &n, &m);
rep(i, , n) {
rep(j, , m) {
scanf("%d", &M[i][j]);
if (M[i][j] == ) {
bx = i;
by = j;
} else if (M[i][j] == ) {
gx = i;
gy = j;
M[i][j] = ;
} else if (M[i][j] == ) {
hx = i;
hy = j;
M[i][j] = ;
}
}
} solve();
} #ifndef ONLINE_JUDGE
printf("time = %d.\n", (int)clock());
#endif return ;
}

【HDOJ】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

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

  3. hdu 1254 推箱子(搜索)

    我写的第一道感觉比较难的搜索 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1254 首先要推箱子的话要满足人能够在箱子旁边,而且人的对面也是可通的. ...

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

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

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

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

  6. [HDU 1254] 推箱子

    推箱子 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 推箱子(嵌套搜索,bfs中有dfs)

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

随机推荐

  1. zookeeper实现互斥锁

    简单的说,zookeeper就是为了解决集群环境中数据一致性的问题. 举个很简单栗子: 有一个变量A,分别存在于两台服务器中,某个程序需要用到变量A,就随机地访问其中一台服务器并取得变量A的值,对吧? ...

  2. iOS开发,多个button数组,每个数组只能选中5项,多个数组只能选择3个。

    由于常用xib,所以不想用代码写那么多个button.而且也懒的算位置 直接xib拉线成四个数组.水果,零食,饮料,甜点. 入题实现的功能就是,在这四个数组之中只能在3个数组只选中5项.有点绕(就比如 ...

  3. AngularJS的学习网站及相关资源整理

    学习angularjs的网站及相关资源的整理,会不断更新. angularJs的官网:https://angularjs.org/       API文档:https://docs.angularjs ...

  4. poj代码搬家啦啦啦

    我的poj代码搬家啦,大家想看可以到 blog.csdn.net/michaelysm 来看.欢迎哦

  5. java.lang.StringBuilder源码分析

    StringBuilder是一个可变序列的字符数组对象,它继承自AbstractStringBuilder抽象类.它不保证同步,设计出来的目的是当这个字符串缓存只有单线程使用的时候,取代StringB ...

  6. iOS 简单理解类的本质

    1.类也是个对象 类是一个对象是Class类型的对象简称类对象 Class类型的定义 // 一个任意的类型,表示一个Objective-C类 typedef struct objc_class *Cl ...

  7. Vsftpd -- 验证方式

    vsftpd程序提供的FTP服务可选认证方式,分别为匿名访问.本地用户和虚拟用户: 匿名访问:任何人无需验证口令即可登入FTP服务端. 本地用户:使用FTP服务器中的用户.密码信息. 虚拟用户:创建独 ...

  8. Web前端新人笔记之CSS字体

    本章内容是阅读CSS权威指南的一个小积累和随笔.新人必看,老鸟也可查看并指出不足指出以便后人阅读更好地理解.O(∩_∩)O谢谢!!!设置字体属性时样式变的最常见的用途之一:不过,尽管字体选择很重要,但 ...

  9. CSS3之渐变效果

    在css3出来之前,想要出现渐变效果必须就要制作一张图片.不过css3的出现使得渐变效果变得简单.由于不是所有的浏览器都支持css3,所以不是所有的浏览器都能够呈现出css3的效果出来.因此目前大部分 ...

  10. asp.net+MVC--1

    1.MVC入门 1)第一个路由: /*任何应用程序启动时发生的动作都应该存在于单独的类中,并且仅在该方法中按照正确顺序调用*/        protected void Application_St ...