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. HTML阻止冒泡事件的发生

    阻止事件冒泡函数(低级标签的点击事件触发后,上级标签的点击事件再触发,此函数就是防止冒泡事件发生) function stopEventBubble(event){ var e=event || wi ...

  2. Git和Github的基本操作

    一.了解Git和Github 1.什么是GIT? Git是一个免费.开源的版本控制软件 2.什么是版本控制系统? 版本控制是一种记录一个或若干个文件内容变化,以便将来查阅特定版本修订情况得系统. 系统 ...

  3. react 为组件添加样式

    width/height/fontSize:可以直接写数字: style={ width:200,height:200 } 其他带数字的可以:数字+'px' style={ lineHeight:20 ...

  4. 课外知识----base64加密

    每3个字符产生4位的base64字符,不足3个字符,将用“=”补齐至4位base64字符 例如 00--->  MDA= 000--->MDAw base64加密特点 加密后的字符数是4的 ...

  5. poj3417lca+树上差分

    /* 给定n个点的树,在其中加入m条新边(称为非树边) 现在可以割断一条树边,一条非树边,使图分裂成两个联通块,请问有几种切割方式 对树边进行分情况讨论 如果树边不处在环中,则割断这条树边后可以割断任 ...

  6. 停止Monkey

    adb shell top | grep monkey adb shell kill id

  7. spring cloud Config--server

    概述 使用Config Server,您可以在所有环境中管理应用程序的外部属性.客户端和服务器上的概念映射与Spring Environment和PropertySource抽象相同,因此它们与Spr ...

  8. springboot配置Druid监控

    整体步骤: (1)    ——   Druid简单介绍,具体看官网: (2)     —— 在pom.xml配置druid依赖包: (3)    ——  配置application.propertie ...

  9. 开启或停止website

    1.添加:Microsoft.Web.Administration 2.代码: static void Main(string[] args) { var server = new ServerMan ...

  10. war的创建