Bloxorz I POJ - 3322 (bfs)
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)的更多相关文章
- Bloxorz I (poj 3322 水bfs)
Language: Default Bloxorz I Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 5443 Acce ...
- Find The Multiple POJ - 1426 (BFS)
题目大意 给定一个整数,寻找一个只有0,1构成的十进制数使得这个数能够整除这个整数 解法 直接bfs第一位放入1,之后每一位放入1或者0 代码 #include <iostream> #i ...
- POJ.1426 Find The Multiple (BFS)
POJ.1426 Find The Multiple (BFS) 题意分析 给出一个数字n,求出一个由01组成的十进制数,并且是n的倍数. 思路就是从1开始,枚举下一位,因为下一位只能是0或1,故这个 ...
- 深搜(DFS)广搜(BFS)详解
图的深搜与广搜 一.介绍: p { margin-bottom: 0.25cm; direction: ltr; line-height: 120%; text-align: justify; orp ...
- 【算法导论】图的广度优先搜索遍历(BFS)
图的存储方法:邻接矩阵.邻接表 例如:有一个图如下所示(该图也作为程序的实例): 则上图用邻接矩阵可以表示为: 用邻接表可以表示如下: 邻接矩阵可以很容易的用二维数组表示,下面主要看看怎样构成邻接表: ...
- 深度优先搜索(DFS)与广度优先搜索(BFS)的Java实现
1.基础部分 在图中实现最基本的操作之一就是搜索从一个指定顶点可以到达哪些顶点,比如从武汉出发的高铁可以到达哪些城市,一些城市可以直达,一些城市不能直达.现在有一份全国高铁模拟图,要从某个城市(顶点) ...
- 【BZOJ5492】[HNOI2019]校园旅行(bfs)
[HNOI2019]校园旅行(bfs) 题面 洛谷 题解 首先考虑暴力做法怎么做. 把所有可行的二元组全部丢进队列里,每次两个点分别向两侧拓展一个同色点,然后更新可行的情况. 这样子的复杂度是\(O( ...
- 深度优先搜索(DFS)和广度优先搜索(BFS)
深度优先搜索(DFS) 广度优先搜索(BFS) 1.介绍 广度优先搜索(BFS)是图的另一种遍历方式,与DFS相对,是以广度优先进行搜索.简言之就是先访问图的顶点,然后广度优先访问其邻接点,然后再依次 ...
- 图的 储存 深度优先(DFS)广度优先(BFS)遍历
图遍历的概念: 从图中某顶点出发访遍图中每个顶点,且每个顶点仅访问一次,此过程称为图的遍历(Traversing Graph).图的遍历算法是求解图的连通性问题.拓扑排序和求关键路径等算法的基础.图的 ...
随机推荐
- Confluence 6 用户宏示例 - Hello World
下面示例显示了如何创建一个用户宏,在这个用户宏中显示文本 'Hello World!' 和任何用户在宏内容中输入的内容. Macro name helloworld Visibility Visibl ...
- ios 逆向编程(环境搭建)
首先如果你想要逆向其他的APP 动态的查看 或者修改人家APP里面的东西 1, 首先要有一台越狱的手机 最好是9.1以下的,因为9.2以上(包括9.2)就不能完美越狱了 2,手机也要5s以上的(因为从 ...
- js 获取当前的网址
http://www.xcx.cc/index.php/home/index/ind?idf=12321var $cur_url=window.location.href; //获取全部的网址var ...
- js获取url参数值,并解决中文乱码
<script type="text/javascript"> function GetQueryString(name) { var reg = new RegExp ...
- 《剑指offer》旋转数组中的最小数字
本题来自<剑指offer> 旋转数组中的最小数字 题目: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素. 例 ...
- PDF怎么编辑,如何旋转PDF页面方向
很多的时候,无论是工作中,还是在学习中都会遇到PDF文件,对于PDF文件,熟悉的小伙伴知道,在编辑PDF文件的时候,是需要使用到PDF编辑软件的,那么,在编辑PDF文件的时候,需要旋转文件的页面,这时 ...
- 最小标示法模板 poj1509
最小标示法:给定一个字符串,不断将其最后一个字符放到开头,最终会得到n个字符串,称这n个字符串循环同构,这些字符串中字典序最小的一个,就是最小表示法 #include<iostream> ...
- tarjan求lca :并查集+dfs
//参考博客 https://www.cnblogs.com/jsawz/p/6723221.html#include<bits/stdc++.h> using namespace std ...
- excel生成数据
Sub function1()Dim i As LongFor i = 1 To 1000000Cells(i, 1) = "A" & iCells(i, 2) = &qu ...
- C++ Primer 笔记——智能指针
1.新的标准库提供了两种智能指针类型,shared_ptr允许多个指针指向同一个对象,unique_ptr则独占所指的对象.标准库还定义了一个名为weak_ptr的伴随类,它是一种弱引用,指向shar ...