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

After Little Tom passes several stages of the game, he finds it much harder than he expected. So he turns to your help.

Input

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.

Output

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.  

Sample Input

7 7
#######
#..X###
#..##O#
#....E#
#....E#
#.....#
#######
0 0

Sample Output

10

题意:一个1*1*2的长方体木块,进行滚动,当1*1的一面着地时,称其为‘立’。那么给你一张地图,#代表不能触碰,.代表空地,X代表木块接触的地方(可能有两个),O代表终点,E代表易碎点(木块不能立在上面),求出从起点到终点的最短距离
思路:既然是最短距离,我们很容易想到bfs
那么我们就需要先确定木块状态,我们用0表示木块立着,1表示木块横躺,2表示木块竖躺。
那么用一个结构体三元组(x,y,kind),记录当前状态,横躺时x、y记录y较小的方块,竖躺时x、y记录x较小的方块
另外,我们用next_x【kind】【4】,表示不同状态向四个方向滚动时,x坐标的变化,next_y也一样。
next_kind【kind】【4】表示不同状态下,向各个方向滚动时,状态的变化。 预处理X的时候,我看到另一种处理方法,就是先将地图信息存入数组,然后扫描到第一个X的时候,判断它上下左右是否有X,有就要把这两个X变成.,然后判断原来的位置是否时X(若有则变成了.),是的话kind = 0,不是就判断第二个X在哪个位置
#include<iostream>
#include<cstdio>
#include<string.h>
#include<queue>
using namespace std; int next_x[][] = {-,,,,-,,,,-, ,,};
int next_y[][] = {,,-,,,,-,,,,-,};
int next_kind[][] = {,,,,,,,,,,,};
int vis[][][];
int r,c;
char maps[][];
struct Node
{
int x,y;
int kind;
Node(int x = ,int y = ,int kind = ):x(x),y(y),kind(kind) {}
}; int bfs(Node st,Node ends)
{
int flag = ;
memset(vis,,sizeof(vis));
queue<Node>que;
while(!que.empty())
que.pop();
vis[st.x][st.y][st.kind] = ;
que.push(st);
while(!que.empty())
{
Node tmp = que.front();
que.pop();
for(int i=; i<; i++)
{
int xx = tmp.x + next_x[tmp.kind][i];
int yy = tmp.y + next_y[tmp.kind][i];
int k_kind = next_kind[tmp.kind][i];
if(k_kind == && xx <= r && xx >= && yy <= c && yy >= && !vis[xx][yy][k_kind] && maps[xx][yy] == '.')
{
vis[xx][yy][k_kind] = vis[tmp.x][tmp.y][tmp.kind] + ;
que.push(Node(xx,yy,k_kind));
}
else if(k_kind == && xx >= && xx <= r && yy >= && yy + <= c && !vis[xx][yy][k_kind] && maps[xx][yy] != '#' && maps[xx][yy+] != '#')
{
vis[xx][yy][k_kind] = vis[tmp.x][tmp.y][tmp.kind] + ;
que.push(Node(xx,yy,k_kind));
}
else if(k_kind == && xx + <= r && xx >= && yy >= && yy <= c && !vis[xx][yy][k_kind] && maps[xx][yy] != '#' && maps[xx+][yy] != '#')
{
vis[xx][yy][k_kind] = vis[tmp.x][tmp.y][tmp.kind] + ;
que.push(Node(xx,yy,k_kind));
}
if(tmp.x == ends.x && tmp.y == ends.y && tmp.kind == ends.kind)
{
return vis[ends.x][ends.y][ends.kind]-;
}
}
}
return -;
} int main()
{
while(~scanf("%d%d",&r,&c) && r && c)
{
char s[];
int start = ;
Node st;
Node ends;
for(int i=; i<=r; i++)
{
for(int j=; j<=c; j++)
{
scanf(" %c",&maps[i][j]);
if(!start && maps[i][j] == 'X')
{
st.x = i;
st.y = j;
st.kind = ;
start++;
maps[i][j] = '.';
}
else if(maps[i][j] == 'X')
{
if(i == st.x)
st.kind = ;
else
st.kind = ;
maps[i][j] = '.';
}
else if(maps[i][j] == 'O')
{
ends.x = i;
ends.y = j;
ends.kind = ;
maps[i][j] = '.';
}
}
}
int flag = bfs(st,ends);
if(flag == -)printf("Impossible\n");
else printf("%d\n",flag);
}
}

Bloxorz I POJ - 3322 (bfs)的更多相关文章

  1. Bloxorz I (poj 3322 水bfs)

    Language: Default Bloxorz I Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 5443   Acce ...

  2. Find The Multiple POJ - 1426 (BFS)

    题目大意 给定一个整数,寻找一个只有0,1构成的十进制数使得这个数能够整除这个整数 解法 直接bfs第一位放入1,之后每一位放入1或者0 代码 #include <iostream> #i ...

  3. POJ.1426 Find The Multiple (BFS)

    POJ.1426 Find The Multiple (BFS) 题意分析 给出一个数字n,求出一个由01组成的十进制数,并且是n的倍数. 思路就是从1开始,枚举下一位,因为下一位只能是0或1,故这个 ...

  4. 深搜(DFS)广搜(BFS)详解

    图的深搜与广搜 一.介绍: p { margin-bottom: 0.25cm; direction: ltr; line-height: 120%; text-align: justify; orp ...

  5. 【算法导论】图的广度优先搜索遍历(BFS)

    图的存储方法:邻接矩阵.邻接表 例如:有一个图如下所示(该图也作为程序的实例): 则上图用邻接矩阵可以表示为: 用邻接表可以表示如下: 邻接矩阵可以很容易的用二维数组表示,下面主要看看怎样构成邻接表: ...

  6. 深度优先搜索(DFS)与广度优先搜索(BFS)的Java实现

    1.基础部分 在图中实现最基本的操作之一就是搜索从一个指定顶点可以到达哪些顶点,比如从武汉出发的高铁可以到达哪些城市,一些城市可以直达,一些城市不能直达.现在有一份全国高铁模拟图,要从某个城市(顶点) ...

  7. 【BZOJ5492】[HNOI2019]校园旅行(bfs)

    [HNOI2019]校园旅行(bfs) 题面 洛谷 题解 首先考虑暴力做法怎么做. 把所有可行的二元组全部丢进队列里,每次两个点分别向两侧拓展一个同色点,然后更新可行的情况. 这样子的复杂度是\(O( ...

  8. 深度优先搜索(DFS)和广度优先搜索(BFS)

    深度优先搜索(DFS) 广度优先搜索(BFS) 1.介绍 广度优先搜索(BFS)是图的另一种遍历方式,与DFS相对,是以广度优先进行搜索.简言之就是先访问图的顶点,然后广度优先访问其邻接点,然后再依次 ...

  9. 图的 储存 深度优先(DFS)广度优先(BFS)遍历

    图遍历的概念: 从图中某顶点出发访遍图中每个顶点,且每个顶点仅访问一次,此过程称为图的遍历(Traversing Graph).图的遍历算法是求解图的连通性问题.拓扑排序和求关键路径等算法的基础.图的 ...

随机推荐

  1. C#判断日期是否合法

  2. WinSCP安装与使用

      WinSCP 是一个 Windows 环境下使用的 SSH(Source Shell)的开源图形化 SFTP(SSH File Transfer Protocol) 客户端.同时支持 SCP(So ...

  3. vuecli3初尝试(转载)

    https://segmentfault.com/a/1190000016423943 在vue-cli3中安装element-ui 其中两种方式自己选择 格式化代码 使用yarn lint命令自动格 ...

  4. gulp前端工程化教程

    gulp npm install -g gulp-concat 文件打包 npm install -g gulp-rename 文件重命名 npm install -g gulp-imagemin 图 ...

  5. 开源框架 ImageLoader +ListView+GridView+RecyclerView 浅解

    下载地址 链接:https://pan.baidu.com/s/1ebz99pcuvHg2bODgeOtSbg 提取码:ia39 一.导入jar包或者添加依赖 jar包地址 导入jar包:将下载的ja ...

  6. 反向找related_name以及limit_fields_to

    问题2:客户的添加页面,通过popup创建用户时 解决方案: 如果新创建的用户时:如果是销售部的人,页面才增加 目的是:拿到limit_choices_to,就可以判断了 当有两个Foreignkey ...

  7. OAuth2 token

    1.资源服务器 package com.ruhuanxingyun.config; import com.fasterxml.jackson.databind.ObjectMapper; import ...

  8. Loadrunner常用目录、组成部分及负载测试流程

    常用目录 bin:存放一些可执行程序 classes:可能用到的jar包 My Template:存放一些自己创建的模板 include:头文件(可以编写自定义函数,保存成.h的头文件形式并放在这个目 ...

  9. Oracle索引(Index)介绍使用

    1.什么是引 索引是建立在表的一列或多个列上的辅助对象,目的是加快访问表中的数据:Oracle存储索引的数据结构是B*树,位图索引也是如此,只不过是叶子节点不同B*数索引:索引由根节点.分支节点和叶子 ...

  10. 如何让谷歌浏览器支持跨域访问(AJAX) AJAX调试跨域接口

    以谷歌最新版本为例(2018) 1.在电脑上新建一个目录,例如:C:\MyChromeDevUserData 2.在属性页面中的目标输入框里加上   --disable-web-security -- ...