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[3][4] = {-2,1,0,0,-1,1,0,0,-1, 2,0,0}; int next_y[3][4] = {0,0,-2,1,0,0,-1,2,0,0,-1,1}; int next_kind[3][4] = {2,2,1,1,1,1,0,0,0,0,2,2}; int vis[505][505][3]; int r,c; char maps[505][505]; struct Node { int x,y; int kind; Node(int x = 0,int y = 0,int kind = 0):x(x),y(y),kind(kind) {} }; int bfs(Node st,Node ends) { int flag = 0; memset(vis,0,sizeof(vis)); queue<Node>que; while(!que.empty()) que.pop(); vis[st.x][st.y][st.kind] = 1; que.push(st); while(!que.empty()) { Node tmp = que.front(); que.pop(); for(int i=0; i<4; 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 == 0 && xx <= r && xx >= 1 && yy <= c && yy >= 1 && !vis[xx][yy][k_kind] && maps[xx][yy] == '.') { vis[xx][yy][k_kind] = vis[tmp.x][tmp.y][tmp.kind] + 1; que.push(Node(xx,yy,k_kind)); } else if(k_kind == 1 && xx >= 1 && xx <= r && yy >=1 && yy + 1 <= c && !vis[xx][yy][k_kind] && maps[xx][yy] != '#' && maps[xx][yy+1] != '#') { vis[xx][yy][k_kind] = vis[tmp.x][tmp.y][tmp.kind] + 1; que.push(Node(xx,yy,k_kind)); } else if(k_kind == 2 && xx + 1<= r && xx >= 1 && yy >= 1 && yy <= c && !vis[xx][yy][k_kind] && maps[xx][yy] != '#' && maps[xx+1][yy] != '#') { vis[xx][yy][k_kind] = vis[tmp.x][tmp.y][tmp.kind] + 1; 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]-1; } } } return -1; } int main() { while(~scanf("%d%d",&r,&c) && r && c) { char s[505]; int start = 0; Node st; Node ends; for(int i=1; i<=r; i++) { for(int j=1; j<=c; j++) { scanf(" %c",&maps[i][j]); if(!start && maps[i][j] == 'X') { st.x = i; st.y = j; st.kind = 0; start++; maps[i][j] = '.'; } else if(maps[i][j] == 'X') { if(i == st.x) st.kind = 1; else st.kind = 2; maps[i][j] = '.'; } else if(maps[i][j] == 'O') { ends.x = i; ends.y = j; ends.kind = 0; maps[i][j] = '.'; } } } int flag = bfs(st,ends); if(flag == -1)printf("Impossible\n"); else printf("%d\n",flag); } }
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 09小结:封装结果集或实体类时,有多个对象的解决方法
- 序列化与反序列化Serializable,Externalizable
- response.getWriter().write()和 response.getWriter().print()的区别:
- java使用TCP,由客户端向服务端传输图片,(电脑与电脑)或(同一台电脑)
- 使用druid
- UDP实现多人聊天室
- 请求(doFilter)与响应乱码(BaseController+自定义注解@ContentType(““))集中处理
- 反射:Reflect(获取类对象三种方法)
- getParameterMap()返回参数需要对应实体类类型,否则收不到----打卡
- 类对象 与 类的对象
- Lambda什么时候使用+简化匿名内部类
- PreparedStatement连接数据库实现登录验证,避免sql注入问题
- 自己封装数据库工具类
- Git---->Linux常用命令+主干、分支合并,发生冲突+当紧急任务来时,文件暂存+忽略文件不提交
- 使用servlet完成简单的登录功能(servlet与html之间跳转(重定向))