立体推箱子是一个风靡世界的小游戏。

游戏地图是一个N行M列的矩阵,每个位置可能是硬地(用”.”表示)、易碎地面(用”E”表示)、禁地(用”#”表示)、起点(用”X”表示)或终点(用”O”表示)。

你的任务是操作一个1×1×2的长方体。

这个长方体在地面上有两种放置形式,“立”在地面上(1×1的面接触地面)或者“躺”在地面上(1×2的面接触地面)。

在每一步操作中,可以按上下左右四个键之一。

按下按键之后,长方体向对应的方向沿着棱滚动90度。

任意时刻,长方体不能有任何部位接触禁地,并且不能立在易碎地面上。

字符”X”标识长方体的起始位置,地图上可能有一个”X”或者两个相邻的”X”。

地图上唯一的一个字符”O”标识目标位置。

求把长方体移动到目标位置(即立在”O”上)所需要的最少步数。

在移动过程中,”X”和”O”标识的位置都可以看作是硬地被利用。

输入格式

输入包含多组测试用例。

对于每个测试用例,第一行包括两个整数N和M。

接下来N行用来描述地图,每行包括M个字符,每个字符表示一块地面的具体状态。

当输入用例N=0,M=0时,表示输入终止,且该用例无需考虑。

输出格式

每个用例输出一个整数表示所需的最少步数,如果无解则输出”Impossible”。

每个结果占一行。

数据范围

3≤N,M≤5003≤N,M≤500

输入样例:

  1. 7 7
  2. #######
  3. #..X###
  4. #..##O#
  5. #....E#
  6. #....E#
  7. #.....#
  8. #######
  9. 0 0

输出样例:

  1. 10

算法:bfs

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <queue>
  4.  
  5. using namespace std;
  6.  
  7. const int maxn = 5e2+;
  8.  
  9. struct rec {
  10. int x, y, lie;
  11. };
  12.  
  13. int n, m;
  14. char Map[maxn][maxn];
  15. int step[maxn][maxn][]; //存储步数
  16. int dir[][] = {, -, , , -, , , }; //普通方向数组
  17. //设0是立着,1是横着,2是竖着,这三种状态
  18. int next_x[][] = {{, , -, }, {, , -, }, {, , -, }};
  19. int next_y[][] = {{-, , , }, {-, , , }, {-, , , }};
  20. int next_lie[][] = {{, , , }, {, , , }, {, , , }};
  21. struct rec st, ed; //分别是起点和终点位置
  22.  
  23. bool valid(int x, int y) { //判断是否越界
  24. if(x <= || x > n || y <= || y > m) {
  25. return false;
  26. }
  27. return true;
  28. }
  29.  
  30. void parse_st_ed() { //找起点和终点
  31. for(int i = ; i <= n; i++) {
  32. for(int j = ; j <= m; j++) {
  33. if(Map[i][j] == 'O') {
  34. ed.x = i;
  35. ed.y = j;
  36. ed.lie = ;
  37. Map[i][j] = '.';
  38. }
  39. if(Map[i][j] == 'X') {
  40. for(int k = ; k < ; k++) {
  41. int dx = dir[k][] + i;
  42. int dy = dir[k][] + j;
  43. if(valid(dx, dy) && Map[dx][dy] == 'X') {
  44. st.x = min(dx, i);
  45. st.y = min(dy, j);
  46. st.lie = k < ? : ; //在dir数组里,0和1是左右,2和3是上下
  47. Map[i][j] = Map[dx][dy] = '.';
  48. break;
  49. }
  50. }
  51. if(Map[i][j] == 'X') {
  52. st.x = i;
  53. st.y = j;
  54. st.lie = ;
  55. Map[i][j] = '.';
  56. }
  57. }
  58. }
  59. }
  60. }
  61.  
  62. bool check(rec next) {
  63. if(!valid(next.x, next.y)) {
  64. return false;
  65. }
  66. if(Map[next.x][next.y] == '#') {
  67. return false;
  68. }
  69. //判断当前位置是否可行
  70. if(next.lie == && Map[next.x][next.y] != '.') {
  71. return false;
  72. }
  73. if(next.lie == && Map[next.x][next.y + ] == '#') {
  74. return false;
  75. }
  76. if(next.lie == && Map[next.x + ][next.y] == '#') {
  77. return false;
  78. }
  79. return true;
  80. }
  81.  
  82. int bfs() {
  83. for(int i = ; i <= n; i++) {
  84. for(int j = ; j <= m; j++) {
  85. for(int k = ; k < ; k++) {
  86. step[i][j][k] = -;
  87. }
  88. }
  89. }
  90. queue<rec> q;
  91. step[st.x][st.y][st.lie] = ;
  92. q.push(st);
  93. while(!q.empty()) {
  94. rec now = q.front();
  95. q.pop();
  96. for(int i = ; i < ; i++) {
  97. rec next;
  98. next.x = now.x + next_x[now.lie][i];
  99. next.y = now.y + next_y[now.lie][i];
  100. next.lie = next_lie[now.lie][i];
  101. if(check(next) && step[next.x][next.y][next.lie] == -) {
  102. step[next.x][next.y][next.lie] = step[now.x][now.y][now.lie] + ;
  103. q.push(next);
  104. if(next.x == ed.x && next.y == ed.y && next.lie == ed.lie) {
  105. return step[next.x][next.y][next.lie];
  106. }
  107. }
  108. }
  109. }
  110. return -; //无解
  111. }
  112.  
  113. int main() {
  114. while(~scanf("%d %d", &n, &m)) {
  115. if(n == && m == ) {
  116. break;
  117. }
  118. for(int i = ; i <= n; i++) {
  119. for(int j = ; j <= m; j++) {
  120. cin >> Map[i][j];
  121. }
  122. }
  123. parse_st_ed();
  124. int ans = bfs();
  125. if(ans != -) {
  126. printf("%d\n", ans);
  127. } else {
  128. printf("Impossible\n");
  129. }
  130. }
  131.  
  132. return ;
  133. }

AcWing:172. 立体推箱子(bfs)的更多相关文章

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

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

  2. HDU 1254 推箱子 BFS

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

  3. 推箱子 BFS

    [编程题] 推箱子 大家一定玩过“推箱子”这个经典的游戏.具体规则就是在一个N*M的地图上,有1个玩家.1个箱子.1个目的地以及若干障碍,其余是空地.玩家可以往上下左右4个方向移动,但是不能移动出地图 ...

  4. HDU1254:推箱子(bfs+dfs)

    传送门 题意 给出一副图 0.空地1.墙2.箱子3.目的地4.人所在的位置 问最少几步能将箱子推到目的地 分析 这道题难度略大(菜鸡),首先用vis[bx][by][mx][my]记录当箱子(bx,b ...

  5. hdu - 1254 推箱子 (bfs+bfs)

    http://acm.hdu.edu.cn/showproblem.php?pid=1254 题目意思很简单,只要思路对就好. 首先考虑搬运工能否到达推箱子的那个点,这个可以根据箱子前进方向得出搬运工 ...

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

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

  7. HDU 1254 推箱子(BFS)

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

  8. HDU1254 推箱子(BFS) 2016-07-24 14:24 86人阅读 评论(0) 收藏

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

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

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

随机推荐

  1. div布局(持续更新)

    1. 效果: 代码: <!DOCTYPE html> <html> <head> <meta name="viewport" conten ...

  2. 当在terminal中输入一行命令的时候,查找的顺序如何看

    大多数时候,尤其是安装了anaconda的时候,我们常常会知道,实际上因为conda的环境变量写到了该用户下的.bashrc下面,所以在terminial敲如python的时候,会显示conda的py ...

  3. shell与其他语言不同点

    1.定义变量时,变量名不加美元符号($,PHP语言中变量需要),如: your_name="w3cschool.cn" 注意,变量名和等号之间不能有空格,这可能和你熟悉的所有编程语 ...

  4. linux命令详解——sed

    sed是一个很好的文件处理工具,本身是一个管道命令,主要是以行为单位进行处理,可以将数据行进行替换.删除.新增.选取等特定工作,下面先了解一下sed的用法 sed命令行格式为:          se ...

  5. STM32 HSE模式配(旁路模式、非旁路模式)

    1.外部晶体/陶瓷谐振器(HSE晶体)模式 这种模式用得比较常见,HSE晶体可以为系统提供较为精确的时钟源.在时钟控制寄存器RCC_CR中的HSERDY位用来指示高速外部振荡器是否稳定.在启动时,直到 ...

  6. SVN搭建以及客户端使用

    第1章 CentOS下搭建SVN服务器 1.1 SVN简介 SVN是Subversion的简称,是一个开放源代码的版本控制系统,相较于RCS.CVS,它采用了分支管理系统,它的设计目标就是取代CVS. ...

  7. Keepalived + Haproxy + PXC 理论篇

    最终模型: 将Kp1 + Kp2 分别和Ha1和Ha2部署在一起,同时绑定VIP ip,对外提供访问,同时监控本机的Haproxy的可用性 通过Ha1 + Ha2 为PXC提供负载均衡,分发请求到后端 ...

  8. shell脚本基础和grep文本处理工具企业应用2

    shell脚本编程:        编程语言的分类:        根据运行方式            编译运行:源代码-->编译器(编译)-->程序文件                优 ...

  9. 腾讯数据安全专家谈联邦学习开源项目FATE:通往隐私保护理想未来的桥梁

    数据孤岛.数据隐私以及数据安全,是目前人工智能和云计算在大规模产业化应用过程中绕不开的“三座大山”. “联邦学习”作为新一代的人工智能算法,能在数据不出本地的情况下,实现共同建模,提升AI模型的效果, ...

  10. Java语言基础(15)

    1 综合案例 Demo1 设计一个父类Shape(图形类),抽象类常量:public static final double PI = 3.14;抽象方法:void show():输出每一个属性值vo ...