诡异的楼梯

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 7642    Accepted Submission(s): 1830

Problem Description
Hogwarts正式开学以后,Harry发现在Hogwarts里,某些楼梯并不是静止不动的,相反,他们每隔一分钟就变动一次方向. 
比如下面的例子里,一开始楼梯在竖直方向,一分钟以后它移动到了水平方向,再过一分钟它又回到了竖直方向.Harry发现对他来说很难找到能使得他最快到达目的地的路线,这时Ron(Harry最好的朋友)告诉Harry正好有一个魔法道具可以帮助他寻找这样的路线,而那个魔法道具上的咒语,正是由你纂写的. 
 
Input
测试数据有多组,每组的表述如下:
第一行有两个数,M和N,接下来是一个M行N列的地图,'*'表示障碍物,'.'表示走廊,'|'或者'-'表示一个楼梯,并且标明了它在一开始时所处的位置:'|'表示的楼梯在最开始是竖直方向,'-'表示的楼梯在一开始是水平方向.地图中还有一个'S'是起点,'T'是目标,0<=M,N<=20,地图中不会出现两个相连的梯子.Harry每秒只能停留在'.'或'S'和'T'所标记的格子内.
 
Output
只有一行,包含一个数T,表示到达目标的最短时间. 
注意:Harry只能每次走到相邻的格子而不能斜走,每移动一次恰好为一分钟,并且Harry登上楼梯并经过楼梯到达对面的整个过程只需要一分钟,Harry从来不在楼梯上停留.并且每次楼梯都恰好在Harry移动完毕以后才改变方向.
 
Sample Input
**..T
**.*.
..|..
.*.*.
S....
Sample Output
7
 
Hint

Hint

地图如下:

 
Source
 
Recommend
JGShining   |   We have carefully selected several similar problems for you:  1072 1026 1240 1253 1242 

  
  bfs广搜。
  在广搜的基础框架之上加了一个“会旋转的楼梯”,楼梯有2个初始状态 “|” 和 “-” ,每移动一次楼梯就变化一次(| => -  ; - => |)。每移动一次用时一分钟,如果遇到楼梯时,正好能通过,则直接跳到楼梯对面,时间+1(也就是说2个格子只用了1分钟);如果恰好不能通过,则在原地等待1分钟。问从初始位置(S)到终点(T)的最短时间。
  这道题的重点是遇到楼梯的处理,可以先用遇到楼梯时的步数(step)来判断,然后用遇到楼梯时的方向(i)来判断。
  处理方法如下:
   if   |    //遇到的楼梯初始是‘|’
    if step是奇数,变化
      if i 是奇数
        不能通过
      else
        能通过
    else  //不变
      if i 是奇数
        能通过
      else
        不能通过
  if -   //遇到的楼梯初始是‘-’
    if step是奇数,变化
      if i 是奇数
        能通过
      else
        不能通过
    else  //不变
      if i 是奇数
        不能通过
      else
        能通过

另外注意两点:

  1.剪枝。有一个可以剪枝的地方:遇到楼梯先判断楼梯对面是否走过,如果已经走过,直接退出本次循环。

  2.超时问题。一定要处理好step(遇到楼梯时的步数),因为step是会变的,所以这次如果不能通过,下次也一定能通过。像我一开始把“step”整成了不会变的,测试结果对了,提交却一直超时。

代码: 
 #include <iostream>
#include <queue>
#include <string.h>
using namespace std;
char a[][];
bool isw[][];
int dx[] = {,,,-};
int dy[] = {,,-,};
int M,N;
int startx,starty;
bool pass; //能否通过梯子
struct NODE{
int x;
int y;
int step;
};
int abs(int n)
{
return n>?n:-n;
}
bool judge(int x,int y,int i,int step)
{
if( x< || y< || x>M ||y>N ) //越界
return ;
if( isw[x][y] ) //走过了
return ;
if( a[x][y]=='*' ) //遇到墙
return ;
if( a[x][y]=='|' ){
if( isw[x+dx[i]][y+dy[i]] )
return ;
if( step% ){ //奇,变
if( i% ) //奇数
pass = false; //不可以通过
else
pass = true; //可以通过
}
else { //不变
if( i% ) //奇数
pass = true; //可以通过
else
pass = false; //不可以通过
}
}
else if( a[x][y]=='-' ){
if( isw[x+dx[i]][y+dy[i]] )
return ;
if( step% ){ //奇,变
if( i% ) //奇数
pass = true; //可以通过
else
pass = false; //不可以通过
}
else{ //不变
if( i% ) //奇数
pass = false; //不可以通过
else
pass = true; //可以通过
}
}
return ;
}
int bfs(int x,int y)
{
queue <NODE> q;
NODE cur,next;
cur.x = x;
cur.y = y;
cur.step = ;
q.push(cur); //第一个节点入队
while(!q.empty()){
//队首出队
cur = q.front();
q.pop();
if(a[cur.x][cur.y]=='T') //如果这一步已经走到了终点,则输出走到这一步的步数
return cur.step;
for(int i=;i<;i++){ //下一层节点入队
int nx = cur.x + dx[i];
int ny = cur.y + dy[i];
if( judge(nx,ny,i,cur.step) ) //判定这一步可走否
continue;
if(a[nx][ny]=='|' || a[nx][ny]=='-'){ //如果这一步是碰到梯子的
if(pass){ //可以通过梯子
nx += dx[i];
ny += dy[i];
}
else{ //不可以通过梯子
nx -= dx[i];
ny -= dy[i];
}
}
next.x = nx; //可走,记录下一步的位置
next.y = ny;
next.step = cur.step + ; //可走,步数累加
isw[next.x][next.y] = true; //可走,标记走过
q.push(next);
}
}
}
int main()
{
while(cin>>M>>N){
for(int i=;i<=M;i++)
for(int j=;j<=N;j++){
cin>>a[i][j];
if(a[i][j]=='S'){
startx = i;
starty = j;
}
}
memset(isw,,sizeof(isw));
isw[startx][starty] = true;
cout<<bfs(startx,starty)<<endl;
}
return ;
}

Freecode : www.cnblogs.com/yym2013

hdu 1180:诡异的楼梯(BFS广搜)的更多相关文章

  1. hdu 1180 诡异的楼梯(广搜,简单)

    题目 挺简单的一道广搜题,只要用判断时间是偶数还是奇数就可以判断楼梯的方位,但是我这傻逼居然写了那么久啊那么久,我果然秀逗了,,,, #define _CRT_SECURE_NO_WARNINGS # ...

  2. HDU 1180 诡异的楼梯 (广搜)

    题目链接 Problem Description Hogwarts正式开学以后,Harry发现在Hogwarts里,某些楼梯并不是静止不动的,相反,他们每隔一分钟就变动一次方向. 比如下面的例子里,一 ...

  3. hdu 1180 诡异的楼梯 (bfs)

    诡异的楼梯 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Sub ...

  4. hdu 1180诡异的楼梯(bfs)

    诡异的楼梯 Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 131072/65536K (Java/Other) Total Submis ...

  5. hdu - 1180 诡异的楼梯 (bfs+优先队列)

    http://acm.hdu.edu.cn/showproblem.php?pid=1180 注意点就是楼梯是在harry移动完之后才会改变方向,那么只要统计到达这个点时间奇偶性,就可以知道当前楼梯是 ...

  6. HDU 1180 诡异的楼梯(超级经典的bfs之一,需多回顾)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1180 诡异的楼梯 Time Limit: 2000/1000 MS (Java/Others)     ...

  7. HDU 1180 诡异的楼梯(BFS)

    诡异的楼梯 Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status ...

  8. HDU 1180 诡异的楼梯【BFS/楼梯随时间变化】

    诡异的楼梯 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others) Total Submis ...

  9. HDOJ/HDU 1180 诡异的楼梯(经典BFS-详解)

    Problem Description Hogwarts正式开学以后,Harry发现在Hogwarts里,某些楼梯并不是静止不动的,相反,他们每隔一分钟就变动一次方向. 比如下面的例子里,一开始楼梯在 ...

随机推荐

  1. 几种通讯协议的比较RMI > Httpinvoker >= Hessian >> Burlap >> web service (转)

    一.综述 本文比较了RMI,Hessian,Burlap,Httpinvoker,web service等5种通讯协议的在不同的数据结构和不同数据量时的传输性能.RMI是java语言本身提供的通讯协议 ...

  2. 【LeetCode】69. Sqrt(x) (2 solutions)

    Sqrt(x) Implement int sqrt(int x). Compute and return the square root of x. 解法一:牛顿迭代法 求n的平方根,即求f(x)= ...

  3. 关于flex,好像有12个属性非常重要

    关于Flex,有12个属性非常重要 这几天在学习Flex布局,发现Flex真的好厉害! Flex是Flexible Box的缩写,意为"弹性布局",用来为盒模型提供最大的灵活性. ...

  4. ocr 识别 github 源码

    参考 [1] https://github.com/eragonruan/text-detection-ctpn [2] https://github.com/senlinuc/caffe_ocr [ ...

  5. 从JavaScript 数组去重看兼容性有关问题,及性能优化(摘自玉伯博客)

    JavaScript 数组去重经常出现在前端招聘的笔试题里,比如: 有数组 var arr = ['a', 'b', 'c', '1', 0, 'c', 1, '', 1, 0],请用 JavaScr ...

  6. 使用阿里云Docker镜像加速

    使用docker官方的docker hub速度太慢,正好看到国内阿里云也做了docker镜像,于是想试试看阿里云的docker源.先附上 阿里云docker hub地址 .新用户需要注册成为开发者.打 ...

  7. Quartus调用Modelsim SE避免重复编译Altera器件库的方法

    最近用Quartus 15.0配合Modelsim SE 10.4的64位版本,简直就是闪电一般的仿真速度.但是众所周知,SE版本最大的问题就是每次由Quartus自动调用时,都要重新编译所使用的器件 ...

  8. Windows API中的坑

    本文主页链接:Windows API中的坑 ExpandEnvironmentStrings 风险: 进程会继承其父进程的环境变量.在展开如%APPDATA%等文件夹时,有可能父进程对此环境变量进行过 ...

  9. 找电影资源最强攻略,知道这些你就牛B了!

    找电影资源最强攻略,知道这些你就牛B了! 电影工厂 2015-07-01 · 分享   点击题目下方环球电影,关注中国顶尖电影微杂志 我们也许没有机会去走遍千山万水,却可以通过电影进入各种各样的角色来 ...

  10. html5 indexDB的使用

    angular.module('indexdb', []) .factory('indexDbJs', [function() { const CurDBVersion = 10000; window ...