hdoj 1254 推箱子 【BFS+DFS】
来源:互联网 发布:碧之轨迹优化破解补丁 编辑:程序博客网 时间:2024/06/05 05:09
推箱子
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 6549 Accepted Submission(s): 1866
Problem Description
推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N的房间里有一个箱子和一个搬运工,搬运工的工作就是把箱子推到指定的位置,注意,搬运工只能推箱子而不能拉箱子,因此如果箱子被推到一个角上(如图2)那么箱子就不能再被移动了,如果箱子被推到一面墙上,那么箱子只能沿着墙移动.
现在给定房间的结构,箱子的位置,搬运工的位置和箱子要被推去的位置,请你计算出搬运工至少要推动箱子多少格.
现在给定房间的结构,箱子的位置,搬运工的位置和箱子要被推去的位置,请你计算出搬运工至少要推动箱子多少格.
Input
输入数据的第一行是一个整数T(1<=T<=20),代表测试数据的数量.然后是T组测试数据,每组测试数据的第一行是两个正整数M,N(2<=M,N<=7),代表房间的大小,然后是一个M行N列的矩阵,代表房间的布局,其中0代表空的地板,1代表墙,2代表箱子的起始位置,3代表箱子要被推去的位置,4代表搬运工的起始位置.
Output
对于每组测试数据,输出搬运工最少需要推动箱子多少格才能帮箱子推到指定位置,如果不能推到指定位置则输出-1.
Sample Input
15 50 3 0 0 01 0 1 4 00 0 1 0 01 0 2 0 00 0 0 0 0
Sample Output
4
0ms。
思路:7*7,直接暴力枚举所有状态即可。
首先若把箱子从(x, y)推到(x+1, y),则人必须在(x-1, y)位置,同理其它三种情况也是这样。只需记录该状态下箱子的位置(x, y)和人的位置(mx, my),判断(mx, my)能否到达(x-1, y)位置即可。这样写好后,提交就WA了。
仔细推敲后,发现在人三面被堵且只有一面是箱子的情况下(或许还有其他情况),不能单纯标记,这样或许得到的不是最优解(可能箱子回到原来的位置才是最优)。人必须要先把箱子推走才可以进行下一步活动,这样的话在未来的某个状态下箱子或许会回到原来的位置。因此在标记状态时,可累计两次。
AC代码:
#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <algorithm>#include <queue>#include <stack>#include <map>#include <set>#include <vector>#define INF 0x3f3f3f3f#define eps 1e-8#define MAXN (300+10)#define MAXM (100000)#define Ri(a) scanf("%d", &a)#define Rl(a) scanf("%lld", &a)#define Rf(a) scanf("%lf", &a)#define Rs(a) scanf("%s", a)#define Pi(a) printf("%d\n", (a))#define Pf(a) printf("%.2lf\n", (a))#define Pl(a) printf("%lld\n", (a))#define Ps(a) printf("%s\n", (a))#define W(a) while(a--)#define CLR(a, b) memset(a, (b), sizeof(a))#define MOD 1000000007#define LL long long#define lson o<<1, l, mid#define rson o<<1|1, mid+1, r#define ll o<<1#define rr o<<1|1using namespace std;int n, m;int Map[10][10];bool judge(int x, int y){ return x >= 0 && x < n && y >= 0 && y < m;}int vis[10][10];bool use[10][10];int Move[4][2] = {0,1, 0,-1, 1,0, -1,0};bool DFS(int x, int y, int tx, int ty){ use[x][y] = true; if(x == tx && y == ty) return true; for(int i = 0; i < 4; i++) { int xx = x + Move[i][0]; int yy = y + Move[i][1]; if(!judge(xx, yy) || Map[xx][yy] == 1 || use[xx][yy]) continue; if(DFS(xx, yy, tx, ty)) return true; } return false;}struct Node{ int x, y, step; int mx, my;};int sx, sy, tx, ty;int BFS(int x, int y){ queue<Node> Q; CLR(vis, 0); Node now, next; now.x = x; now.y = y; now.step = 0; vis[now.x][now.y] = 1; now.mx = sx, now.my = sy; Q.push(now); while(!Q.empty()) { now = Q.front(); Q.pop(); if(Map[now.x][now.y] == 3) return now.step; for(int i = 0; i < 4; i++) { next.x = now.x + Move[i][0];//箱子下一步移动位置 next.y = now.y + Move[i][1]; if(!judge(next.x, next.y) || vis[next.x][next.y] > 2 || Map[next.x][next.y] == 1) continue; int xx, yy;//人的目标位置,到这里才可以把箱子推到(next.x, next.y) switch(i) { case 0: xx = now.x + Move[1][0]; yy = now.y + Move[1][1]; break; case 1: xx = now.x + Move[0][0]; yy = now.y + Move[0][1]; break; case 2: xx = now.x + Move[3][0]; yy = now.y + Move[3][1]; break; case 3: xx = now.x + Move[2][0]; yy = now.y + Move[2][1]; break; } if(!judge(xx, yy) || Map[next.x][next.y] == 1) continue; int t; t = Map[now.x][now.y]; Map[now.x][now.y] = 1; CLR(use, false); if(DFS(now.mx, now.my, xx, yy))//人从上次停留的位置 能否 到达目标位置 { vis[next.x][next.y]++; next.step = now.step + 1; next.mx = now.x; next.my = now.y; Q.push(next); } Map[now.x][now.y] = t; } } return -1;}int main(){ int t; Ri(t); W(t) { Ri(n); Ri(m); for(int i = 0; i < n; i++) { for(int j = 0; j < m; j++) { Ri(Map[i][j]); if(Map[i][j] == 4) { sx = i; sy = j; } if(Map[i][j] == 2) { tx = i; ty = j; } } } Pi(BFS(tx, ty)); } return 0;}
0 0
- HDOJ 1254 推箱子(bfs+dfs)
- hdoj 1254 推箱子 【BFS+DFS】
- HDOJ 1254 推箱子【bfs && dfs】
- HDOJ 1254 推箱子 (BFS)
- hdoj 1254 推箱子(BFS + BFS)
- HDOJ 1254 推箱子 (双BFS)
- hdu 1254 推箱子 (bfs +dfs)
- 【BFS+DFS】hdu 1254 推箱子
- HDU 1254 - 推箱子(BFS + DFS)
- HDU 1254推箱子(bfs+dfs)
- HDU 1254:推箱子【DFS && BFS】
- HDU 1254 推箱子 (BFS + DFS)
- HDU 1254 推箱子(BFS + DFS)
- hdu 1254 推箱子 (bfs+dfs+预处理)
- hdu 1254 推箱子(BFS+BFS或BFS+DFS)
- hdu1254 推箱子 (bfs+dfs)
- hdoj1254推箱子【dfs+bfs】
- hdu1254 推箱子 【bfs+dfs】
- HDU 1754 I Hate It(线段树-区间求最值&&单点修改)
- 关闭eclipse自动弹出console功能
- 条件选择结构<1>__笔记(3)
- Redis 集群规范
- iOS小技巧15-改变UITabBarItem 字体颜色
- hdoj 1254 推箱子 【BFS+DFS】
- Android 异步加载图片,使用LruCache和SD卡或手机缓存,效果非常的流畅
- Android 内存泄漏分析工具LeakCanary
- php让你头疼的浮点数运算
- 你從來不缺智慧,缺的是......
- Image Lazy Load:那些延时加载图片的开源插件(jQuery)
- git push -f
- String转化为byte[]和byte[]转化为String
- Hibernate count和sum查询