hdu - 1254 推箱子 (bfs+bfs)

http://acm.hdu.edu.cn/showproblem.php?pid=1254

题目意思很简单,只要思路对就好。

首先考虑搬运工能否到达推箱子的那个点,这个可以根据箱子前进方向得出搬运工需要到达的目的地,用另一个bfs判断,然后就类似两个点的bfs那样用一个数组标记状态,

需要注意箱子在边上的情况。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<queue>
  4 using namespace std;
  5
  6 struct point
  7 {
  8     int x,y,nx,ny,step;
  9 };
 10
 11 int n,m;
 12 int maze[10][10];
 13 int used[10][10][10][10];
 14 int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
 15
 16 bool bfs1(int a,int b,int c,int d,int p,int q)
 17 {
 18     int mark[10][10];
 19     memset(mark,0,sizeof(mark));
 20     queue<point>que;
 21     point s;
 22     s.x=a,s.y=b;
 23     mark[s.x][s.y]=1;
 24     que.push(s);
 25     while(!que.empty())
 26     {
 27         point e=que.front();que.pop();
 28         //printf("%d %d\n",e.x,e.y);
 29         if(e.x==c&&e.y==d) return true;
 30         for(int i=0;i<4;i++)
 31         {
 32             s.x=e.x+dir[i][0];
 33             s.y=e.y+dir[i][1];
 34             if(s.x==p&&s.y==q) continue;
 35             //printf("%d %d\n",s.x,s.y);
 36             if(s.x>=0&&s.x<n&&s.y>=0&&s.y<m&&maze[s.x][s.y]!=1&&!mark[s.x][s.y])
 37             {
 38                 mark[s.x][s.y]=1;
 39                 que.push(s);
 40             }
 41         }
 42     }
 43     return false;
 44 }
 45
 46 void bfs2(int a,int b,int c,int d)
 47 {
 48     memset(used,0,sizeof(used));
 49     queue<point>que;
 50     point s,e;
 51     s.x=a,s.y=b,s.nx=c,s.ny=d,s.step=0;
 52     que.push(s);
 53     used[s.x][s.y][s.nx][s.ny]=1;
 54     while(!que.empty())
 55     {
 56         e=que.front();que.pop();
 57         //printf("%d %d %d %d %d\n",e.x,e.y,e.nx,e.ny,e.step);
 58         if(maze[e.x][e.y]==3) {printf("%d\n",e.step);return;}
 59         for(int i=0;i<4;i++)
 60         {
 61             s.x=e.x+dir[i][0];
 62             s.y=e.y+dir[i][1];
 63             s.nx=e.x;
 64             s.ny=e.y;
 65             if(s.x<0||s.x>=n||s.y<0||s.y>=m||maze[s.x][s.y]==1||used[s.x][s.y][s.nx][s.ny]) continue;
 66             if(i==0)
 67             {
 68                 if(e.x+1>=n||maze[e.x+1][e.y]==1||(bfs1(e.nx,e.ny,e.x+1,e.y,e.x,e.y)==false)) continue;
 69             }
 70             else if(i==1)
 71             {
 72                 if(e.x-1<0||maze[e.x-1][e.y]==1||(bfs1(e.nx,e.ny,e.x-1,e.y,e.x,e.y)==false)) continue;
 73             }
 74             else if(i==2)
 75             {
 76                 if(e.y+1>=m||maze[e.x][e.y+1]==1||(bfs1(e.nx,e.ny,e.x,e.y+1,e.x,e.y)==false)) continue;
 77             }
 78             else if(i==3)
 79             {
 80                 if(e.y-1<0||maze[e.x][e.y-1]==1||bfs1(e.nx,e.ny,e.x,e.y-1,e.x,e.y)==false) continue;
 81             }
 82             used[s.x][s.y][s.nx][s.ny]=1;
 83             s.step=e.step+1;
 84             que.push(s);
 85         }
 86     }
 87     printf("-1\n");
 88 }
 89
 90 int main()
 91 {
 92     //freopen("a.txt","r",stdin);
 93     int t,a,b,c,d;
 94     scanf("%d",&t);
 95     while(t--)
 96     {
 97         scanf("%d%d",&n,&m);
 98         for(int i=0;i<n;i++)
 99             for(int j=0;j<m;j++)
100             {
101                 scanf("%d",&maze[i][j]);
102                 if(maze[i][j]==2)
103                 {
104                     a=i;
105                     b=j;
106                 }
107                 else if(maze[i][j]==4)
108                 {
109                     c=i;
110                     d=j;
111                 }
112             }
113         bfs2(a,b,c,d);
114     }
115     return 0;
116 }
时间: 2024-12-10 01:43:06

hdu - 1254 推箱子 (bfs+bfs)的相关文章

HDU 1254 推箱子

一个很有意思的 BFS+DFS.附 数据. 本来今天的任务是多重背包,结果为了帮别人找WA点,自己也坑在这道题上了. 最后想了一组自己都没过的数据-发现想法都不对-果断换思路了. 正确思路是以箱子为起点做BFS找最短.每次移动的时候DFS判断人能不能移动到箱子的后面. 开始就我写一个BFS,什么数据都过了.这组过不了 1 7 4 0 0 0 0 0 0 1 0 0 2 0 3 1 4 1 0 1 0 1 0 1 0 1 0 1 0 0 0 实际上答案是2. 我写的是总步数最短时,箱子的最短步数.

HDU 1254——推箱子

这题跟 hdu 1734 push box 是一样的,只不过这题推的是一个箱子,另外求的是箱子被推了多少次,那么只要在箱子被推的时候 次数才加1,然后使用优先队列就ok了 写了1734就会觉得这题很水啦  HDU1734题解 网上主流的都是bfs+bfs,或者是bfs+dfs <span style="font-size:18px;">#include<iostream> #include<cstring> #include<algorithm

搜索 [HDU 1254] 推箱子

推箱子 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 5343    Accepted Submission(s): 1503 Problem Description 推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N的房间里有一个箱子和一个搬运工,搬运工的工作就是把箱子推到指定的位置,注意,搬运工只能推箱子而不能拉箱子

HDU 1254 推箱子 BFS

囧,一开始没有管人的情况,只看箱子,果然SB了. #include <cstdio> #include <cstring> #include <iostream> #include <map> #include <set> #include <vector> #include <string> #include <queue> #include <deque> #include <bitset

hdu 1254(推箱子游戏bfs+状态标记)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1254 推箱子 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 5181    Accepted Submission(s): 1439 Problem Description 推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N

suseoj 1212: 推箱子问题(bfs)

1212: 推箱子问题 时间限制: 1 Sec  内存限制: 128 MB提交: 60  解决: 13[提交][状态][讨论版][命题人:liyuansong] 题目描述 码头仓库是划分为n×m个格子的矩形阵列.有公共边的格子是相邻格子.当前仓库中有的格子是空闲的,有的格子则已经堆放了沉重的货物.由于堆放的货物很重,单凭仓库管理员的力量是无法移动的.仓库管理员有一项任务:要将一个小箱子推到指定的格子上去.管理员可以在仓库中移动,但不能跨过已经堆放了货物的格子.管理员站在与箱子相对的空闲格子上时,

poj 1254 推箱子

New~ 欢迎“热爱编程”的高考少年——报考杭州电子科技大学计算机学院 关于2015年杭电ACM暑期集训队的选拔 欢迎参加: 浙江杭电{安控杯}Hackthon 推箱子 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6027    Accepted Submission(s): 1721 Problem Description 推箱子

HDU 1254 (经典游戏)推箱子 BFS+dfs

Problem Description 推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N的房间里有一个箱子和一个搬运工,搬运工的工作就是把箱子推到指定的位置,注意,搬运工只能推箱子而不能拉箱子,因此如果箱子被推到一个角上(如图2)那么箱子就不能再被移动了,如果箱子被推到一面墙上,那么箱子只能沿着墙移动. 现在给定房间的结构,箱子的位置,搬运工的位置和箱子要被推去的位置,请你计算出搬运工至少要推动箱子多少格. Input 输入数据的第一行是一个整数T(1<=T<=20),代表测试

hdu 1254(两个BFS) 推箱子

http://acm.hdu.edu.cn/showproblem.php?pid=1254 首先,要判断人是不是可以从4到达箱子的位置2,而且不止判断一次,因为推动箱子一步后,人的位置也会改变,所以每次移动箱子前都要判断 所以这里要用两个搜索,当每朝着一个方向移动一步箱子的时候,就需要判断 从 此刻的 人位置能不能到达箱子反方向的那个位置(人只能推箱子, 不能拉什么的)  注意人在移动的时候箱子对于人来说也算障碍物,这里需要开一个hash1的四维数组记录走过的位置,不然会死循环超时间 这个记录