这题做的一把鼻涕一把泪,果断考虑不周555

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
  1. #include <cstdio>
  2. #include <queue>
  3. using namespace std;
  4. const int dir[][] = {,,,-,,,-,};
  5. int m, n, map[][];
  6.  
  7. struct node
  8. {
  9. int x, y, step;
  10. int man_x, man_y;
  11.  
  12. bool check(void)
  13. {
  14. if(x>= && x<m && y>= && y<n)
  15. {
  16. if(map[x][y] != )
  17. {
  18. return true;
  19. }
  20. }
  21. return false;
  22. }
  23. }start, man, temp, next, u, v;
  24.  
  25. bool BFS_Man(void)
  26. {
  27. start.x = temp.man_x;
  28. start.y = temp.man_y;
  29.  
  30. int mark[][] = {};
  31. mark[start.x][start.y] = ;
  32.  
  33. queue<node>que;
  34. que.push(start);
  35.  
  36. while(!que.empty())
  37. {
  38. u = que.front();
  39. que.pop();
  40. if(u.x == man.x && u.y == man.y)
  41. {
  42. return true;
  43. }
  44. for(int i=;i<;i++)
  45. {
  46. v.x = u.x + dir[i][];
  47. v.y = u.y + dir[i][];
  48. if(v.check() && !mark[v.x][v.y] && (v.x != temp.x || v.y != temp.y)) //越界,撞墙,重复,撞箱子
  49. {
  50. mark[v.x][v.y] = ;
  51. que.push(v);
  52. }
  53. }
  54. }
  55. return false;
  56. }
  57.  
  58. int BFS_Box(void)
  59. {
  60. int mark[][][] = {}; //判重的时候需要一个三维数组,箱子从不同方向过来,人的位置是不一样的,也就意味着状态不一样
  61.  
  62. queue<node>que;
  63. que.push(start);
  64.  
  65. while(!que.empty())
  66. {
  67. temp = que.front();
  68. que.pop();
  69.  
  70. if(map[temp.x][temp.y] == ) //找到返回步数
  71. {
  72. return temp.step;
  73. }
  74.  
  75. for(int i=;i<;i++)
  76. {
  77. next.x = temp.x + dir[i][];
  78. next.y = temp.y + dir[i][];
  79. next.step = temp.step + ;
  80. if(next.check() && mark[next.x][next.y][i] == ) //判断越界,撞墙,重复
  81. {
  82. man.x = temp.x - dir[i][];
  83. man.y = temp.y - dir[i][]; //人移动的目标坐标
  84. if(man.check()) //判断目标坐标是否越界,撞墙
  85. {
  86. if(BFS_Man()) //搜索判断人是否可以移动到目标点
  87. {
  88. next.man_x = temp.x;
  89. next.man_y = temp.y; //更新当前人坐标
  90.  
  91. mark[next.x][next.y][i] = ;
  92. que.push(next);
  93. }
  94. }
  95. }
  96. }
  97. }
  98. return -;
  99. }
  100.  
  101. int main()
  102. {
  103. int T;
  104. scanf("%d",&T);
  105. while(T--)
  106. {
  107. scanf("%d%d",&m,&n);
  108. for(int i=;i<m;i++)
  109. {
  110. for(int j=;j<n;j++)
  111. {
  112. scanf("%d",&map[i][j]);
  113. if(map[i][j] == ) //记录箱子起点
  114. {
  115. start.x = i;
  116. start.y = j;
  117. start.step = ;
  118. }
  119. else if(map[i][j] == ) //记录人起点
  120. {
  121. start.man_x = i;
  122. start.man_y = j;
  123. }
  124. }
  125. }
  126. printf("%d\n",BFS_Box());
  127. }
  128. return ;
  129. }

HDU_1254——推箱子,两次BFS的更多相关文章

  1. 推箱子 (hdu1254)(bfs双重广搜)

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

  2. hdu 1254 推箱子(双重bfs)

    题目链接 Problem Description 推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N的房间里有一个箱子和一个搬运工,搬运工的工作就是把箱子推到指定的位置,注意,搬运工只能 ...

  3. 推箱子 HDU1254 (bfs)

    较难的bfs 有两种方法做 一种双重bfs: 主bfs是箱子   还要通过dfs判断人是否能到箱子后面 用inmap函数的好处.. 箱子要用三位数组来标记  因为箱子可以回到原来到过的地方  因为推的 ...

  4. hdu_1254_推箱子(双BFS)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1254 题解:以箱子为主体,第一层BFS,然后用第二层BFS来判断人是否可以到达,这里细节比较多,要注意 ...

  5. poj 1475 Pushing Boxes 推箱子(双bfs)

    题目链接:http://poj.org/problem?id=1475 一组测试数据: 7 3 ### .T. .S. #B# ... ... ... 结果: //解题思路:先判断盒子的四周是不是有空 ...

  6. 【GDOI2015】 推箱子 状态压缩+bfs

    请注意$8$是一个美妙的数字 考虑到$8\times 8=64$,而一个unsigned long long是$64$位的,所以考虑用一个$01$状态存储箱子.考虑到箱子能转动,那么四种情况都存一下就 ...

  7. hdu 1254(两个BFS) 推箱子

    http://acm.hdu.edu.cn/showproblem.php?pid=1254 首先,要判断人是不是可以从4到达箱子的位置2,而且不止判断一次,因为推动箱子一步后,人的位置也会改变,所以 ...

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

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

  9. HDU 1254 推箱子 BFS

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

随机推荐

  1. Redis的AOF功能

    引言:  Redis是基于内存的数据库,同时也提供了若干持久化的方案,允许用户把内存中的数据,写入本地文件系统,以备下次重启或者当机之后继续使用.本文将描述如何基于Redis来设置AOF功能 什么是R ...

  2. CSS从大图中抠取小图完整教程(background-position应用) (转)

    自认为把background-position的应用讲得非常通俗易懂的教材.做个记号. 相信很多喜欢研究网页界面的童鞋都遇到过一个奇妙的现象:网页中很多图片素材被合成在一张图片上. 起初小菜模仿网站的 ...

  3. 正则表达式匹配(python)

    获取图片的python代码 #coding=utf-8 import urllib import re def getHtml(url): page = urllib.urlopen(url) htm ...

  4. webconfig的设置节点几个说明

    有助于深入理解webconfig <?xml version="1.0" encoding="utf-8" ?> <configuration ...

  5. 黑马程序员-for和foreach

    class Program { static void Main(string[] args) { Console.WriteLine("***第一种情况****************** ...

  6. EXPDP IMPDP 知识总结

    Data Pump Export ATTACH Default: job currently in the user's schema, if there is only one Purpose(目的 ...

  7. 【转】UITextView 修改键盘 的return按钮

    原文:http://www.apkbus.com/blog-107838-45740.html 1 #import <UIKit/UIKit.h>2 3 @interface TextVi ...

  8. Cocos2dx 3.2 节点之间相互通信与设置触摸吞噬的方法

    实际开发中,我们经常会遇到这样的情况.我们有一个层layer1,这个层包含一个menu层,menu1层里又包含了一个节点按钮button1.现在需要实现一个效果:点击button1弹出一个对话框,这个 ...

  9. I/O复用-select模型

    IO复用: I/O复用使得程序可以同时监听多个文件描述符,这对提高程序的性能至关重要.例如TCP服务器要同时处理监听socket和连接socket,客户端要同时处理用户输入和网络连接. Linux下实 ...

  10. 为什么struts2 ajax 方法执行两次

    struts2中使用json插件执行ajax处理时,如果方法名是get方法的时候,方法会莫名其妙的执行两次. 原因: struts2 中JSON的原理是在ACTION中的get方法都会序列化,所以前面 ...