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

游戏地图是一个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≤500
输入样例:
7 7
#######
#…X###
#…##O#
#…E#
#…E#
#…#
#######
0 0
输出样例:
10

思路:
状态很难找》》》对于每个点有3个状态,箱子立在格子上,箱子横放再格子(格子在最右边),箱子竖放在格子上(格子在最上边)。
然后根据这个状态,确定四个方向的坐标变换。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;struct Node
{int x,y;int lie;
};Node st,ed;
char a[505][505];
int n,m;
int dirx[] = {0,0,1,-1},diry[] = {1,-1,0,0};//左右上下
int d[505][505][3];int Dx[3][4] =  {{0, 0,-2,1}, {0 ,0,-1,1}, {0 ,0,-1,2} };//左右上下
int Dy[3][4] =  {{-2,1, 0,0}, {-1,2,0 ,0}, {-1,1,0 ,0} };//立(.) 横(——) 竖(|)
int Dl[3][4] = {{1 ,1, 2,2}, {0 ,0,1 ,1}, {2 ,2,0 ,0} };bool check1(Node A)
{int x = A.x,y = A.y;if(x <= n && y <= m && x >= 1 && y >= 1)return true;return false;
}bool check1(int x,int y)
{if(x <= n && y <= m && x >= 1 && y >= 1)return true;return false;
}bool check2(Node A)
{int x = A.x,y = A.y,lie = A.lie;if(!check1(A))return false;if(a[x][y] == '#')return false;if(lie == 0 && a[x][y] != '.')return false;if(lie == 1 && a[x][y + 1] == '#')return false;if(lie == 2 && a[x + 1][y] == '#')return false;return true;
}int bfs()
{queue<Node>q;q.push(Node{st.x,st.y,st.lie});d[st.x][st.y][st.lie] = 0;while(!q.empty()){Node now = q.front();q.pop();int x = now.x,y = now.y,lie = now.lie;for(int i = 0;i < 4;i++){Node nex;nex.x = x + Dx[lie][i];nex.y = y + Dy[lie][i];nex.lie = Dl[lie][i];if(!check1(nex))continue;if(!check2(nex))continue;if(d[nex.x][nex.y][nex.lie] != -1)continue;d[nex.x][nex.y][nex.lie] = d[x][y][lie] + 1;q.push(nex);if(nex.x == ed.x && nex.y == ed.y && nex.lie == ed.lie)return d[nex.x][nex.y][nex.lie];}}return -1;
}int main()
{while(~scanf("%d%d",&n,&m) && n && m){for(int i = 1;i <= n;i++){scanf("%s",a[i] + 1);}for(int i = 1;i <= n;i++){for(int j = 1;j <= m;j++){if(a[i][j] == 'O'){ed.x = i;ed.y = j;ed.lie = 0;a[i][j] = '.';}else if(a[i][j] == 'X'){for(int k = 0;k < 4;k++){int dx = i + dirx[k],dy = j + diry[k];if(check1(dx,dy) && a[dx][dy] == 'X'){st.x = min(i,dx);st.y = min(j,dy);st.lie = k < 2 ? 1 : 2;a[i][j] = a[dx][dy] = '.';}}if(a[i][j] == 'X'){st.x = i;st.y = j;st.lie = 0;}}}}memset(d,-1,sizeof(d));int ans = bfs();if(ans != -1){printf("%d\n",d[ed.x][ed.y][ed.lie]);}else{printf("Impossible\n");}}return 0;
}

ACWING172. 立体推箱子 poj3322(bfs巨麻烦)相关推荐

  1. 172. 立体推箱子

    立体推箱子是一个风靡世界的小游戏. 游戏地图是一个 N 行 M 列的矩阵,每个位置可能是硬地(用 . 表示).易碎地面(用 E 表示).禁地(用 # 表示).起点(用 X 表示)或终点(用 O 表示) ...

  2. LeetCode 1263. 推箱子(BFS+DFS / 自定义哈希set)

    文章目录 1. 题目 2. 解题 2.1 超时解 2.2 BFS + DFS 1. 题目 「推箱子」是一款风靡全球的益智小游戏,玩家需要将箱子推到仓库中的目标位置. 游戏地图用大小为 n * m 的网 ...

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

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

  4. 【HDU - 1254 】推箱子 (双bfs)

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

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

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

  6. hdu 1254 推箱子(嵌套搜索,bfs中有dfs)

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

  7. 【嵌套bfs】A - Pushing Boxes POJ - 1475 推箱子

    https://vjudge.net/contest/387870#problem/A 题目描述 Imagine you are standing inside a two-dimensional m ...

  8. 【BFS】推箱子问题

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

  9. [HDU 1254] 推箱子

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1254 1 #include<cstdio> 2 #include<queue> ...

最新文章

  1. 常用图像额文件格式及类型
  2. Python 量化(四)计算股票的移动平均线
  3. 有关javabean的说法不正确的是_关于 JavaBean, 下列叙述中不正确的是 ( ) 。_学小易找答案...
  4. 作者:张宇中(1969-),男,中国电信股份有限公司云计算分公司首席数据分析师、大数据分析顾问。...
  5. poj3616 基础的动态规划算法 《挑战程序设计竞赛》
  6. gitHub上传项目
  7. 苹果iOS系统源码思考:对象的引用计数存储在哪里?--从runtime源码得到的启示...
  8. href=“javascript:void(0);”和href=void(change_code(this));
  9. 解决企业IT三大运维管理难题
  10. go标准库的学习-encoding/base64
  11. TP6微信公众号登陆授权
  12. 最小公倍数求解完全解读
  13. 黄山市职称计算机报名,黄山职业学校2021中专
  14. postman不跨域 本地开发跨域_为什么postman调接口不会跨域而浏览器会
  15. 定时任务ScheduledExecutorService
  16. 实习每日总结_20161222
  17. 徒步健步打卡活动,徒步过程拍照打卡,让徒步更有趣。box-sizing 属性允许我们在框的总宽度
  18. 红帽 Red Hat Linux相关产品iso镜像下载【百度云】【更新7.6】
  19. Web Worker 初探
  20. matlab中webcam,MATLAB编程-MATLAB2014a的webcam操作

热门文章

  1. 画论30 李澄叟《画山水诀》
  2. Eassy-Jun.25
  3. 乐谱播放器 android,光遇乐谱 免费版
  4. 3des加密 java php_php 3des加密 兼容JAVA 多么痛的领悟呀
  5. SlideLive:提供小清新风格PPT模板下载
  6. 【转】如何更好的进行项目文档管理
  7. An Overview of TVM and Model Optimization TE
  8. CMOS模拟集成电路设计视频课程--即将上线
  9. URP下Alpha从Gamma空间到Linner空间转换(一)——Alpha贴图不叠加
  10. 2022年还有高职扩招全日制大专