题目描述

Little Tom loves playing games. One day he downloads a little computer game called 'Bloxorz' which makes him excited. It's a game about rolling a box to a specific position on a special plane. Precisely, the plane, which is composed of several unit cells, is a rectangle shaped area. And the box, consisting of two perfectly aligned unit cube, may either lies down and occupies two neighbouring cells or stands up and occupies one single cell. One may move the box by picking one of the four edges of the box on the ground and rolling the box 90 degrees around that edge, which is counted as one move. There are three kinds of cells, rigid cells, easily broken cells and empty cells. A rigid cell can support full weight of the box, so it can be either one of the two cells that the box lies on or the cell that the box fully stands on. A easily broken cells can only support half the weight of the box, so it cannot be the only cell that the box stands on. An empty cell cannot support anything, so there cannot be any part of the box on that cell. The target of the game is to roll the box standing onto the only target cell on the plane with minimum moves.

The box stands on a single cell

The box lies on two neighbouring cells, horizontally

The box lies on two neighbouring cells, vertically

The box lies on two neighbouring cells, vertically After Little Tom passes several stages of the game, he finds it much harder than he expected. So he turns to your help.

Bloxorz是一个风靡世界的小游戏。Bloxorz的地图是一个N行M列的矩阵,每个位置可能是硬地(用.表示)、易碎地面(用E表示)、禁地(用#表示)、起点(用X表示)或终点(用O表示)。你的任务是操作一个112的长方体。这个长方体在地面上有两种放置形式,“立”在地面上(11的面接触地面)或者“躺”在地面上(12的面接触地面)。在每一步操作中,可以按上下左右四个键之一。按下之后,长方体向对应的方向沿着棱滚动90度。任意时刻,长方体不能有任何部位接触禁地(否则就会掉下去),并且不能立在易碎地面上(否则会因为压强太大掉下去)。X标识长方体的起始位置,地图上可能有一个X或者两个相邻的X。地图上唯一的一个O标识目标位置。求把长方体移动到目标位置(即立在O上)所需要的最少步数。如果无解,输出Impossible。在移动过程中,X和O标识的位置都可以看作是硬地被利用,3<=N,M<=500。

输入格式

Input contains multiple test cases. Each test case is one single stage of the game. It starts with two integers R and C(3 ≤ R, C ≤ 500) which stands for number of rows and columns of the plane. That follows the plane, which contains R lines and C characters for each line, with 'O' (Oh) for target cell, 'X' for initial position of the box, '.' for a rigid cell, '#' for a empty cell and 'E' for a easily broken cell. A test cases starts with two zeros ends the input.

It guarantees that

There's only one 'O' in a plane.

There's either one 'X' or neighbouring two 'X's in a plane.

The first(and last) row(and column) must be '#'(empty cell).

Cells covered by 'O' and 'X' are all rigid cells.

输出格式

For each test cases output one line with the minimum number of moves or "Impossible" (without quote) when there's no way to achieve the target cell.

样例

样例输入

复制7 7
#######
#..X###
#..##O#
#....E#
#....E#
#.....#
#######
0 0

样例输出

复制10

做题感想,这道题差点把我写颓废了,写了整整一个下午啊啊啊啊,由于个人太弱,一直调不出来是什么鬼,等我交的时候别人都做完了QAQ。

解题思路:其实思路比较简单,就像普通的bfs一样,但是细节有点多,而且代码量不够的人(比如我)写起来超级浪费时间。首先我们要明白,这个方块有三种躺着的方式,我们选择其中xy坐标最小的一个格子作为代表,然后算出方块利用四条边缘移动后的位置和状态:具体的,有x坐标位置,y坐标位置,z状态,其中,x + rx[z][j],y + ry[z][j], z = rz[z][j]分别表示状态原本在xy点的状态为z的点,移动rx[z][j], ry[z][j]后的状态变为rz[z][j],这里的z有三种分别对应0表示立着,1表示横着躺,2表示竖着躺 ,j有四种,分别是四条边缘。

然后我们不断根据题意判断这个点移动后是否满足条件,再次不断bfs,至于初始点的处理妙处,比较简单,详见代码O^O

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std ;
const int MAXN = 600 ;
int rx[4][5] = {{0, 0, -2, 1}, {0, 0, 1, -1}, {-1, 2, 0, 0} } ;//表示状态为i(第一维)的四种边缘x的变化
int ry[4][5] = {{1, -2, 0, 0}, {-1, 2, 0, 0}, {0 ,0, 1, -1} } ;//y的变化
int rz[4][5] = {{1, 1, 2, 2}, {0, 0, 1, 1}, {0, 0, 2, 2} } ;//变化后对应的状态(原数下标分别+x+y后状态为z)
//0表示立着,1表示横着躺,2表示竖着躺 */
int n, m, cnt = 0 ;
struct Node
{int x, y, z ;
}P[4], e ;
char mp[MAXN][MAXN] ;
int Vis[MAXN][MAXN][4], flag = 0 ;
queue<Node> q ;
bool Check(Node a)
{if(mp[a.x][a.y] == '#')    return false ;if(mp[a.x][a.y + 1] == '#' && a.z == 1)    return false ;if(mp[a.x + 1][a.y] == '#' && a.z == 2)    return false ;if(mp[a.x][a.y] != '.' && a.z == 0)  return false ;return true ;
}
void Scan()
{cnt = 0, flag = 0 ;for(int i = 1; i <= n; i ++){scanf("%s", mp[i] + 1) ;for(int j = 1; j <= m; j ++){if(mp[i][j] == 'X'){P[++cnt].x = i, P[cnt].y = j, P[cnt].z = 0 ;mp[i][j] = '.' ;}if(mp[i][j] == 'O'){e.x = i, e.y = j, e.z = 0 ;mp[i][j] = '.' ;}Vis[i][j][0] = Vis[i][j][1] = Vis[i][j][2] = -1 ;} }
}
void BFS()
{Node a ;a = P[1] ;if(cnt == 1)  a.z = 0 ;if(cnt == 2){if(P[1].y = P[2].y - 1 && P[1].x == P[2].x) a.z = 1 ;else a.z = 2 ;}Vis[a.x][a.y][a.z] = 0 ;q.push(a) ;while(q.empty() == 0){a = q.front() ;q.pop() ;if(a.x == e.x && a.y == e.y && a.z == 0){flag = 1 ;printf("%d\n", Vis[a.x][a.y][a.z]) ;while(q.empty() == 0)  q.pop() ;return ; }for(int i = 0; i < 4; i ++){Node b ;b.x = a.x + rx[a.z][i] ;b.y = a.y + ry[a.z][i] ;b.z = rz[a.z][i] ;if(b.x >= 1 && b.y >= 1 && b.x <= n && b.y <= m){if(Vis[b.x][b.y][b.z] == -1 && Check(b) == true){Vis[b.x][b.y][b.z] = Vis[a.x][a.y][a.z] + 1 ;q.push(b) ;}}}}
}
int main()
{while(scanf("%d%d", &n, &m) != EOF){if(n == 0 && m == 0)    return 0 ;Scan() ;BFS() ;if(flag == 0)    printf("Impossible\n") ;}
} 

zanzan

POJ-3322 Bloxorz I相关推荐

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

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

  2. POJ 3322 Bloxorz I(BFS)

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

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

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

  4. POJ 3322 Bloxorz I

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

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

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

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

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

  7. POJ 3322 BFS

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

  8. 【POJ 3322】 Bloxorz I

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

  9. Bloxorz I POJ - 3322 bfs

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

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

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

最新文章

  1. 最新!这所顶尖大学录取线全国第三!毕业生深造率超九成!
  2. Android app动态加载
  3. 关于 PHP 与 MYSQL的链接
  4. Windows Phone开发(46):与Socket有个约会 转:http://blog.csdn.net/tcjiaan/article/details/7669315...
  5. SentinelResource注解配置中_客户自定义限流处理_削峰填谷_流量控制_速率控制_服务熔断_服务降级---微服务升级_SpringCloud Alibaba工作笔记0046
  6. set python_Python之set的用法(一)
  7. [Swustoj 24] Max Area
  8. 给你个选择Mac的理由,浅谈Macos系统的优点
  9. 数据分析工作常见的七种错误及规避技巧
  10. 机器人动力学与控制学习笔记(二)————机器人动力学建模
  11. 纯CSS实现的炫酷HOVER效果
  12. STC8H开发(十二): I2C驱动AT24C08,AT24C32系列EEPROM存储
  13. 近期币圈与美股的相关性
  14. 人脸识别实名制管理,推动智慧工地建设发展
  15. Qt写的json代码生成器
  16. html字体标签设计,36个重要的HTML标签
  17. 主动求变,苏宁易购如何破局2022?
  18. 为什么linux虚拟机文件78g,linux 磁盘空间被占满但找不到目标文件的问题处理 lsof命令...
  19. 如何用AI设计一幅杂志封面
  20. windows开源会有linux吗,微软真的要开源Windows?小伙伴惊呆了!

热门文章

  1. 隧道适配器,本地连接过多的解决办法
  2. 使用nslookup验证DNS的SRV记录
  3. ubuntu桌面特效
  4. 雷达多普勒频率计算公式_非接触式雷达流速仪在水文测量如何运用
  5. 基于vue手写一个分屏器,通过鼠标控制屏幕宽度。
  6. 天基实业要拥有投资理财智慧
  7. c语言apply函数,R语言apply()函数用法(示例代码)
  8. 计算机核心基础知识2
  9. 深圳内推 | 华为诺亚方舟实验室招聘计算机视觉算法研究员/实习生
  10. 立创eda学习笔记十二:常见pcb板布局约束原则