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).图的遍历算法是求解图的连通性问题.拓扑排序和求关键路径等算法的基础.图的 ...
随机推荐
- swift 学习- 17 -- 析构器
// 析构器 只适用与 类类型, 当一个类的实例被释放之前, 析构器会被立即调用, 析构器用关键字 deinit 来标示, 类似于构造器要用 init 来标示 // 析构过程原理 // Swift 会 ...
- Confluence 6 恢复一个站点有关使用站点导出为备份的说明
推荐使用生产备份策略.我们推荐你针对你的生产环境中使用的 Confluence 参考 Production Backup Strategy 页面中的内容进行备份和恢复(这个需要你备份你的数据库和 ho ...
- nginx之请求限制与连接限制
模块limit_conn_module与limit_req_module limit_conn_module语法 limit_req_module语法 附: http长连接与短连接
- Linux基础实操六
实操一: 临时配置网络(ip,网关,dns)+永久配置 #ifconfig ens33 192.168.145.134/24 #vim /etc/resolv.conf #route add defa ...
- laravel 表单方法伪造
有时候,我们可能需要手动定义发送表单数据所使用的 HTTP 请求方式,而 HTML 表单仅支持 GET 和 POST 两种方式,如果要使用其他的方式,则需要自己来定义实现. HTTP 请求方式概述 最 ...
- 闭包&装饰器
闭包 1.函数引用 def test(): print('--test--') # 调用函数 test() # 引用函数 ret = test print(id(ret)) print(id(test ...
- python(9): GUI
实例1: 对输入的所有数字求和, 最后以. 结束输入 def fun(): list1=[] print('input a number:') while True: num=input() if n ...
- 多线程相关-ThreadPoolExecutor
应用层面: ThreadPoolExecutor: 创建多线程池执行器:new ThreadPoolExecutor(),创建方法最终都是走的以下这个构造方法: /** * Creates a new ...
- java & python猜数字游戏对比
1.java版 package day03; import java.util.Random;import java.util.Scanner; /** * 猜数字游戏 * 随机生成一个1-100之间 ...
- C#enum使用Attribute求字段名
用到了一些反射:(自己看吧) public enum UserState { /// <summary> /// 正常 /// </summary> [Remark(" ...