诡异的楼梯

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. How to add a button in the seletions "More"

    <?xml version="1.0" encoding="utf-8"?> <openerp> <data> <re ...

  2. 关于SO_REUSEADDR的使用说明~

    参考WINDOWS   网络编程技术         1.   可以对一个端口进行多次绑定,一般这个是不支持使用的:     2.   对于监听套接字,比较特殊.如果你定义了SO_REUSEADDR, ...

  3. oracle 存储过程 调用动态sql

      oracle 存储过程 调用动态sql CreationTime--2018年8月16日11点25分 Author:Marydon 1.错误实现方式 --开始时间拼接' 00:00:00' V_S ...

  4. iOS 全屏侧滑/UIScrollView/UISlider间滑动冲突

    代码地址如下:http://www.demodashi.com/demo/13848.html 效果预览 一.前期准备 有一个支持全屏侧滑返回的视图控制器ViewController,ViewCont ...

  5. js特效,轻松实现内容的无缝平滑滚动

    <!DOCTYPE   html   PUBLIC   "-//W3C//DTD   XHTML   1.0   Transitional//EN"   "http ...

  6. 快速排序以及第k小元素的线性选择算法

    简要介绍下快速排序的思想:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此 ...

  7. oracle 统计分析函数

    http://www.cnblogs.com/advocate/archive/2010/11/16/1878693.html

  8. atitit.科技公司的超级武器--超级框架,到底要不要自己的框架??

    atitit.科技公司的超级武器--超级框架,到底要不要自己的框架?? 我们生活的时代,,任何一个时代,总有人会以经济之类的理由劝阻人向未知领域探索,基本上,他们的理由无非几种: 1.把钱投到更需要的 ...

  9. commit

    git blame -L  260, 270  a.xml no permissions fastbootsudo chown root:root fastbootsudo chmod +s fast ...

  10. oracle 使用occi方式 批量插入多条数据

    if (vecInfo.empty()) { ; //数据为空,不上传,不上传标志设置为1,只有0表示上传成功 } std::string strUserName = userName; std::s ...