来一发搜索。数据量比较小,这么玩儿都能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. ios code style

    注释 建议使用VVDocumenter插件 多行注释 格式: /** 注释内容 */ 单行注释 格式: ///在对文件.类.函数进行注释时推荐使用多行注释,在函数体内对代码块进行注释时,使用单行注释 ...

  2. 批量杀进程——xargs用途

    ps -ef|grep ora|grep “LOCAL=YES”|awk ‘{print $2}’|xargs –I {} kill -9 {} ps -ef|grep ora|grep “LOCAL ...

  3. 关于懒加载(lazy loading)

    懒加载---即为延迟加载,顾名思义在需要的时候才加载,这样做效率会比较低,但是占用内存低,iOS设备内存资源有限,如果程序启动使用一次性加载的方式可能会耗尽内存,这时可以使用懒加载,先判断是否有,没有 ...

  4. OpenJudge 2680 化验诊断 C++

    链接地址:http://bailian.openjudge.cn/practice/2680 题目: 总时间限制: 1000ms 内存限制: 65536kB 描述 下表是进行血常规检验的正常值参考范围 ...

  5. Pulltorefresh使用中碰到的问题

    第一 在使用XScrollView布局是,无法在该布局.xml文件,放置内容布局控件,假如放置了会报错, <com.markmao.pulltorefresh.widget.XScrollVie ...

  6. ubuntu的syslog为空,停止写入解决方法

    修改syslog权限: chown syslog:adm syslog

  7. call_user_func

    (PHP 4, PHP 5) call_user_func — 把第一个参数作为回调函数调用 mixed call_user_func ( callable $callback [, mixed $p ...

  8. mysql 之权限介绍

    转自:http://tech.it168.com/a2010/0114/837/000000837456_all.shtml 一.MySQL授权表概述首先从全局开始,如果全局的是允许的,即在 user ...

  9. R语言语法笔记

    ## 1. 数据输入 ## a$b # 数据框中的变量 a = 15 # 赋值 a <- 15 # 赋值 a = c(1,2,3,4,5) # 数组(向量) b = a[1] # 数组下标,从1 ...

  10. 【4】创建一个自己的Bootstrap模板

    什么也不说了,直接贴上代码吧,哈哈 <!DOCTYPE html> <html lang="zh-cn"> <head> <meta ch ...