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

游戏地图是一个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. dell 服务器 加ssd硬盘,DELL服务器加SSD硬盘.doc
  2. 在scala中访问postgresql(使用sbt)
  3. idea初始化git 初始化git仓库
  4. 在 Chrome 控制台可以玩的两个骚操作,你知道吗?
  5. 杂记 - 进化成更好的人
  6. Linux中断(interrupt)子系统之二:arch相关的硬件封装层
  7. OpenShift 4 Hands-on Lab (10) 限制集群资源的使用量
  8. python交互式帮助的进入、使用和退出_python退出交互式???
  9. 存储过程生成所有实体类
  10. AQS同步队列结构分析
  11. mdadm命令参数详解
  12. Metronome节拍器
  13. Nutch爬虫爬取视频研究文档
  14. BOSS直聘简历导出为PDF文档
  15. html使用highcharts绘制饼图,Highcharts绘制饼图的简单实例
  16. .NET Conf China 2022 第一批讲师阵容大揭秘!整个期待了!
  17. 赵运泓:12:4下周黄金行情走势分析
  18. 互联网晚报 | 9月5日| 四川甘孜州泸定县发生 6.8 级地震;​西北工业大学遭美国国安局网络攻击;苹果已考虑移除SIM卡插槽...
  19. 写入位置0xccccccc权限冲突
  20. 华为的冬天 (zz.is2120)

热门文章

  1. bind添加SRV记录说明
  2. loadrunner之获取登陆接口中的token值及 LoadRunner数据更新与更新方式
  3. 菜鸟飞行记——二、jQuery miniui知识随记
  4. HTML 页面 DIV 边框圆角
  5. 调音台基础使用说明-功能分布、输入输出连接、通道条使用
  6. 工匠:有工艺专长的匠人。
  7. 项目质量管理的七个基本原理
  8. 计算机软件合同审查要点有,关于技术合同的审核要点清单
  9. 如何使用 Eclipse + Kotlin + tomcat 开发 Dynamic Web Server
  10. Python程序伪编译与打包