ACWING172. 立体推箱子 poj3322(bfs巨麻烦)
立体推箱子是一个风靡世界的小游戏。
游戏地图是一个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巨麻烦)相关推荐
- 172. 立体推箱子
立体推箱子是一个风靡世界的小游戏. 游戏地图是一个 N 行 M 列的矩阵,每个位置可能是硬地(用 . 表示).易碎地面(用 E 表示).禁地(用 # 表示).起点(用 X 表示)或终点(用 O 表示) ...
- LeetCode 1263. 推箱子(BFS+DFS / 自定义哈希set)
文章目录 1. 题目 2. 解题 2.1 超时解 2.2 BFS + DFS 1. 题目 「推箱子」是一款风靡全球的益智小游戏,玩家需要将箱子推到仓库中的目标位置. 游戏地图用大小为 n * m 的网 ...
- hdu.1254.推箱子(bfs + 优先队列)
推箱子 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...
- 【HDU - 1254 】推箱子 (双bfs)
题干: 推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N的房间里有一个箱子和一个搬运工,搬运工的工作就是把箱子推到指定的位置,注意,搬运工只能推箱子而不能拉箱子,因此如果箱子被推到一个 ...
- 推箱子 (hdu1254)(bfs双重广搜)
推箱子 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submissio ...
- hdu 1254 推箱子(嵌套搜索,bfs中有dfs)
推箱子 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...
- 【嵌套bfs】A - Pushing Boxes POJ - 1475 推箱子
https://vjudge.net/contest/387870#problem/A 题目描述 Imagine you are standing inside a two-dimensional m ...
- 【BFS】推箱子问题
题目:大家一定玩过"推箱子"这个经典的游戏.具体规则就是在一个N*M的地图上,有1个玩家.1个箱子.1个目的地以及若干障碍,其余是空地.玩家可以往上下左右4个方向移动,但是不能移动 ...
- [HDU 1254] 推箱子
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1254 1 #include<cstdio> 2 #include<queue> ...
最新文章
- dell 服务器 加ssd硬盘,DELL服务器加SSD硬盘.doc
- 在scala中访问postgresql(使用sbt)
- idea初始化git 初始化git仓库
- 在 Chrome 控制台可以玩的两个骚操作,你知道吗?
- 杂记 - 进化成更好的人
- Linux中断(interrupt)子系统之二:arch相关的硬件封装层
- OpenShift 4 Hands-on Lab (10) 限制集群资源的使用量
- python交互式帮助的进入、使用和退出_python退出交互式???
- 存储过程生成所有实体类
- AQS同步队列结构分析
- mdadm命令参数详解
- Metronome节拍器
- Nutch爬虫爬取视频研究文档
- BOSS直聘简历导出为PDF文档
- html使用highcharts绘制饼图,Highcharts绘制饼图的简单实例
- .NET Conf China 2022 第一批讲师阵容大揭秘!整个期待了!
- 赵运泓:12:4下周黄金行情走势分析
- 互联网晚报 | 9月5日| 四川甘孜州泸定县发生 6.8 级地震;​西北工业大学遭美国国安局网络攻击;苹果已考虑移除SIM卡插槽...
- 写入位置0xccccccc权限冲突
- 华为的冬天 (zz.is2120)