hdu 1254 推箱子(bfs判断路径可达+bfs搜索最小)
2015-04-25 12:27
453 查看
推箱子
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 5982 Accepted Submission(s): 1704
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
1 5 5 0 3 0 0 0 1 0 1 4 0 0 0 1 0 0 1 0 2 0 0 0 0 0 0 0
Sample Output
4
Author
Ignatius.L & weigang Lee
题目分析:
每次推箱子前判断人可达的点,用以判断箱子能否沿某一方向推,两个bfs搞定,在求解的bfs中记录从每个方向到达某点,因为每个点很可能的到达多次,但是从每个方向在获得最优解的情况只会到达一次
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <queue> #define MAX 9 using namespace std; int mp[MAX][MAX]; int mark[MAX][MAX]; int t,n,m,sx,sy,ex,ey,px,py; struct Node { int x1,y1,x2,y2,t; }; int dx[]={0,1,0,-1}; int dy[]={1,0,-1,0}; void judge ( int x , int y , int x2 , int y2 ) { Node a; a.x1 = x , a.y1 = y; queue<Node> q; memset ( mark , 0 , sizeof ( mark ) ); q.push ( a ); mark[x][y] = 1; while ( !q.empty() ) { Node u = q.front(); q.pop(); for ( int i = 0 ; i < 4 ; i++ ) { Node t; t.x1 = u.x1 + dx[i]; t.y1 = u.y1 + dy[i]; if ( mp[t.x1][t.y1] == 1 || (t.x1 == x2 && t.y1 == y2 ) ) continue; if ( mark[t.x1][t.y1] ) continue; mark[t.x1][t.y1] = 1; q.push ( t ); } } } bool used[4][MAX][MAX]; int bfs ( ) { memset ( used , 0 , sizeof ( used ) ); queue<Node> q; Node a; a.x1 = sx , a.y1 = sy , a.x2 = px , a.y2 = py , a.t = 0; q.push ( a ); while ( !q.empty() ) { Node b = q.front(); q.pop(); if ( b.x1 == ex && b.y1 == ey ) return b.t; judge ( b.x2 , b.y2 , b.x1 , b.y1 ); for ( int i = 0 ; i < 4 ; i++ ) { a.x2 = b.x1 , a.y2 = b.y1; a.x1 = b.x1 + dx[i] , a.y1 = b.y1 + dy[i]; a.t = b.t + 1; if ( mp[a.x1][a.y1] == 1 ) continue; if ( used[i][a.x1][a.y1] ) continue; if ( !mark[b.x1-dx[i]][b.y1-dy[i]] ) continue; used[i][a.x1][a.y1] = 1; q.push ( a ); } } return -1; } int main ( ) { scanf ( "%d" , &t ); while ( t-- ) { scanf ( "%d%d" , &n , &m ); for ( int i = 0 ; i < MAX ; i++ ) for ( int j = 0 ; j < MAX ; j++ ) mp[i][j] = 1; for ( int i = 1 ; i <= n ; i++ ) for ( int j = 1 ; j <= m ; j++ ) { scanf ( "%d" , &mp[i][j] ); if ( mp[i][j] == 3 ) ex = i , ey = j; if ( mp[i][j] == 4 ) px = i , py = j; if ( mp[i][j] == 2 ) sx = i , sy = j; } printf ( "%d\n" , bfs ( ) ); } }
相关文章推荐
- hdu 1254 推箱子 很好的嵌套搜索 双层BFS
- HDU 1254 推箱子 (搜索中套搜索,BFS + DFS 这感觉,酸爽!)
- hdu 1254 推箱子(嵌套搜索,bfs中有dfs)
- hdu 1254 推箱子 很好的嵌套搜索 双层BFS
- hdu 4771 Stealing Harry Potter's Precious (2013亚洲区杭州现场赛)(搜索 bfs + dfs) 带权值的路径
- hdu 1254 推箱子(BFS+BFS或BFS+DFS)
- HDU 1254 推箱子 BFS
- 题解: HDU 1254 :推箱子 (BFS)
- HDU1254--推箱子(BFS+DFS)
- HDU 1254 推箱子(双重bfs)
- HDU 1254 推箱子(双BFS)
- hdu - 1254 推箱子 (bfs+bfs)
- HDU 1254 推箱子 搜索中搜索
- hdu 1254 推箱子 (bfs+dfs+预处理)
- HDU 1254 推箱子 推箱子BFS广搜
- hdu_1254_推箱子(双BFS)
- HDU 1254 推箱子 (BFS套BFS)
- HDU 1254 - 推箱子(BFS + DFS)
- HDU 1254 推箱子(双层BFS)
- HDU 1254 推箱子(搜索)