一、内容

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

游戏地图是一个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

二、思路

  • 用(x,y, life)分别表示一个状态,x,y是坐标,life是小块的状态。
  • no_dx,no_dy,no_dlife模拟4个滚动方向上x,y,life的变化
  • d数组记录某一状态走了多少步。

三、代码

#include <cstdio>
#include <queue>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 505;
char g[N][N];
int n, m, d[N][N][3], sx, sy, slife, ex, ey;
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, -1, 1};
int no_dx[3][4] = {{-2, 1, 0, 0}, {-1, 1, 0, 0}, {-1, 2, 0, 0}};
int no_dy[3][4] = {{0, 0, -2, 1}, {0, 0, -1, 2}, {0, 0, -1, 1}};
int no_dlife[3][4] = {{2, 2, 1, 1}, {1, 1, 0, 0}, {0, 0, 2, 2}};
struct node {//life表示小块的状态 0表示立在x,y 1表示横放,左边在x,y 2表示竖放,上边在x,y int x, y, life;node(int x, int y, int life): x(x), y(y), life(life) {}
};
bool ok(int fx, int fy) {if (fx < 0 || fy < 0 || fx >= n || fy >= m) return false;return true;
}
//判断某个滚动是否合法
bool ok(int fx, int fy, int life) { //判断本身那个格子是否合法 if (!ok(fx, fy) || g[fx][fy] == '#') return false;if (life == 0) {if (g[fx][fy] == 'E') return false;return true;} else if(life == 1) {//判断右边格子是否合法if (ok(fx, fy + 1) && g[fx][fy + 1] != '#') return true;return false; } else {//判断下边格子是否合法if (ok(fx + 1, fy) && g[fx + 1][fy] != '#') return true;return false; }
}
void bfs() {queue<node> q;q.push(node(sx, sy, slife));d[sx][sy][slife] = 0;//标记起点为0步 while (q.size()) {node t = q.front();q.pop();//遍历4个方向的情况 for (int i = 0; i < 4; i++) {int fx = no_dx[t.life][i] + t.x;int fy = no_dy[t.life][i] + t.y;int flife = no_dlife[t.life][i];if (ok(fx, fy, flife) && d[fx][fy][flife] == -1) {//代表可以滚动 d[fx][fy][flife] = d[t.x][t.y][t.life] + 1; q.push(node(fx, fy, flife)); if (flife == 0 && fx == ex && fy == ey) {printf("%d\n", d[ex][ey][0]);return;}}} } printf("Impossible\n");
}
int main() {while (scanf("%d%d", &n, &m), n) {for (int i = 0; i < n; i++) {scanf("%s",g[i]); }sx = sy = ex = ey = slife = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) {if (g[i][j] == 'X') {sx = i; sy = j;//判断周围4个方向上有无xfor (int k = 0; k < 4; k++) {int fx = i + dx[k];int fy = j + dy[k];if (ok(fx, fy) && g[fx][fy] == 'X') {sx = min(i, fx);sy = min(j, fy);slife = k < 2 ? 2 : 1;break;} } } else if (g[i][j] == 'O') {ex = i, ey = j;}} }memset(d, -1, sizeof d);bfs();  }return 0;
}

Bloxorz I POJ - 3322 bfs相关推荐

  1. POJ 3322 BFS

    题意 传送门 POJ 3322 Bloxorz I 题解 长方体当前的状态为其横.纵坐标与摆放状态组成的三元组,为了方便表示,只取长方体左上方的位置作为横.纵坐标状态,BFSBFSBFS 求解即可. ...

  2. Bloxorz I POJ - 3322(广度优先搜索)

    题意:传送门 对应游戏:传送门 题解:对于这个木块,可以发现有三个状态,第一个状态是直立的,第二个状态是横躺着,第三个状态是竖躺着,那么状态维护三个值x,y,liex,y,liex,y,lie,分别对 ...

  3. POJ - 3322 Bloxorz I(bfs+状态设计)

    题目链接:点击查看 题目大意:模拟Bloxorz小游戏找出最优解,简单说一下规则,给出一个n*m的矩阵,其中,"#"代表墙,"X"代表起点,"O&qu ...

  4. POJ 3322 Bloxorz I(BFS)

    题意: 要把x所在地方的盒子翻滚到O处,最少需要的滚动次数. 思路: BFS 求最短路径,问题的关键是如何对盒子翻转时,移动状态的一个设计,开了一个三维数组. #include <iostrea ...

  5. poj 3322 Bloxorz I (bfs+辅助数组减代码量)

    很好玩的一个游戏,建议大家做完了去玩一玩~. 方块的状态有3种情况,竖着,横躺着,竖躺着,所以可以用一个标记变量表示. 对于判重,可以开一个三维的数组来判断. 麻烦的地方在于移动,如果直接模拟的话,将 ...

  6. 【POJ 3322】 Bloxorz I

    [题目链接] http://poj.org/problem?id=3322 [算法] 广度优先搜索 [代码] #include <algorithm> #include <bitse ...

  7. POJ 3322 Bloxorz I

    目录 一.题目简介 可以先玩一下这个游戏 点击打开链接 二.题解 三.代码 谢谢! 一.题目简介 可以先玩一下这个游戏 点击打开链接 二.题解 这道题目就是波尔皮,很简单,就是爆搜一通,BFS直接暴力 ...

  8. POJ 3322 Bloxorz I(进阶指南,广搜)

    算法竞赛进阶指南,112页, 广搜,坐标变换 题目意思: 4433 小游戏上面的 推木头游戏,http://www.4399.com/flash/13071.htm#search3 本题要点: 1.长 ...

  9. POJ 3322 Bloxorz(算竞进阶习题)

    bfs 标准广搜题,主要是把每一步可能的坐标都先预处理出来,会好写很多 每个状态对应三个限制条件,x坐标.y坐标.lie=0表示直立在(x,y),lie=1表示横着躺,左半边在(x,y),lie=2表 ...

最新文章

  1. golang 接口_「实战」助力数据库开发之接口篇 - Golang 连接 Greenplum
  2. Python多版本共存配置
  3. B13_NumPy数学函数(三角函数,舍入函数)
  4. 对集合变量定义赋值_SpringBoot配置加载原理(自定义加载配置)
  5. JZOJ5776. 【NOIP2008模拟】小x游世界树
  6. PclZip:强大的PHP压缩与解压缩zip类
  7. 韩山师范计算机科学与技术,韩山师范学院计算机科学与技术专业
  8. 朋友借我10万并把房产证交给我,写了借条,并在借条上写明了用此房产做抵押,有效吗?
  9. L1-079 天梯赛的善良 (20 分)-PAT 团体程序设计天梯赛 GPLT
  10. 吴恩达神经网络和深度学习-学习笔记-28-端到端的深度学习(end-to-end deep learning )
  11. 《火球——UML大战需求分析》(第3章 分析业务模型-类图)——3.7 关于对象图
  12. MS08067红队攻防班 第五期开班啦!(2021年最后一期)
  13. 本地缓存之LIFO、LRU、FIFO、LFU实现
  14. vue-webpack.config使用七牛云cdn镜像加速
  15. Java进度条(excel文件解析)的实现
  16. 为Debian解决Mercury MW150US无线网卡驱动
  17. What?Poly又双叒叕发新品了?
  18. 2-2 组合优化问题-常用模型与通用求解器
  19. 小明一家过桥_智力题(小明一家过桥)
  20. arduino esp8266开发板下载出错解决方法

热门文章

  1. 隧道适配器,本地连接过多的解决办法
  2. 详解Guitar Pro显示和弦图的步骤
  3. POJ3208魔鬼数
  4. poj3208 Apocalypse Someday 题解报告
  5. 四足机器人运动运动控制系统及相关算法、导航系统及相关算法本人硕毕论文发表后再更
  6. 以太网交换机 VLAN 生成树协议
  7. 什么是网络爬虫?它是如何工作的以及如何自动抓取
  8. Android开发——Java代码动态改变图片颜色
  9. kdb 使用手册指导 1
  10. 解构微信(二):团队是研究院、艺术中心甚至学校