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

5 5
**..T
**.*.
..|..
.*.*.
S....

Sample Output

7

Hint
Hint

地图如下:

挺经典的一个广搜题目!
题意很好理解。做的时候理清思路,注意楼梯的方向,楼梯的方向可以用到达时候的时间的奇偶来判断。因为楼梯只有2个方向!上下,或者左右。
移动到楼梯后面也还要判断下是否越界,楼梯对面是不是墙,是不是已经走过,这3个条件,满足了才能过去。
如果到的时候,楼梯方向与过去的方向不同,就只能等待一分钟,在这个时候,位置不动,时间加1!再进入队列。这个顺序很重要!
不能先过去,然后时间加2,再入队列。这样会超内存,这是很多人用优先队列的原因!
(因为这样的话,你会发现,弹出的node型变量的t会出现t-时间小的会在后面弹出,这样增加了内存的使用!!!)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
struct node{int x,y,t;
};
int n,m;
int mx[]={0,1,0,-1};
int my[]={1,0,-1,0};//右,下,左,上
char map[30][30];
int d[30][30];
int tx,ty,sx,sy;
node ft;
int judge(int x,int y){if(x<0||x>=n||y<0||y>=m){return 0;}if(d[x][y]){return 0;}if(map[x][y]=='*'){return 0;}return 1;
}void bfs(){queue<node> q;ft.x=sx;ft.y=sy;ft.t=0;q.push(ft);d[sx][sy]=1;while(!q.empty()){node ff=q.front();q.pop();int x=ff.x;int y=ff.y;if(map[x][y]=='T'){printf("%d\n",ff.t);return;}for(int i=0;i<4;i++){x=ff.x+mx[i];y=ff.y+my[i];if(!judge(x,y)){continue;}node nt;if(map[x][y]=='.'||map[x][y]=='T'){//正常走nt.x=x;nt.y=y;nt.t=ff.t+1;d[nt.x][nt.y]=1;q.push(nt);continue;}else if(i==0||i==2){//右和左if(map[x][y]=='-'&&ff.t%2==0){//可以过去nt.x=x+mx[i];nt.y=y+my[i];if(judge(nt.x,nt.y)){nt.t=ff.t+1;d[nt.x][nt.y]=1;q.push(nt);}}else if(map[x][y]=='|'&&ff.t%2!=0){nt.x=x+mx[i];nt.y=y+my[i];if(judge(nt.x,nt.y)){nt.t=ff.t+1;d[nt.x][nt.y]=1;q.push(nt);}}else {//不能过楼梯,得等一分钟nt.x=ff.x;nt.y=ff.y;nt.t=ff.t+1;d[nt.x][nt.y]=1;q.push(nt);}}else{//上和下if(map[x][y]=='|'&&ff.t%2==0){//可以过去nt.x=x+mx[i];nt.y=y+my[i];if(judge(nt.x,nt.y)){nt.t=ff.t+1;d[nt.x][nt.y]=1;q.push(nt);}}else if(map[x][y]=='-'&&ff.t%2!=0){nt.x=x+mx[i];nt.y=y+my[i];if(judge(nt.x,nt.y)){nt.t=ff.t+1;d[nt.x][nt.y]=1;q.push(nt);}}else {//不能过楼梯,得等一分钟nt.x=ff.x;nt.y=ff.y;nt.t=ff.t+1;d[nt.x][nt.y]=1;q.push(nt);}}}}
}int main(){while(~scanf("%d%d",&n,&m)){memset(d,0,sizeof(d));for(int i=0;i<n;i++){scanf("%s",map[i]);for(int j=0;j<m;j++){if(map[i][j]=='S'){sx=i,sy=j;}}}bfs();}return 0;
}测试数据:
/*
3 3
S|.
-..
T..
5 5
**..T
**.*.
..|..
.*.*.
S....
3 4
S|.|
-T-.
.|..
20 20
S.|.|.|.|.|.|.|.|.|.
.|.|.|.|.|.|.|.|.|.|
|.|.|.|.|.|.|.|.|.|.
.|.|.|.|.|.|.|.|.|.|
|.|.|.|.|.|.|.|.|.|.
.|.|.|.|.|.|.|.|.|.|
|.|.|.|.|.|.|.|.|.|.
.|.|.|.|.|.|.|.|.|.|
|.|.|.|.|.|.|.|.|.|.
.|.|.|.|.|.|.|.|.|.|
|.|.|.|.|.|.|.|.|.|.
.|.|.|.|.|.|.|.|.|.|
|.|.|.|.|.|.|.|.|.|.
.|.|.|.|.|.|.|.|.|.|
|.|.|.|.|.|.|.|.|.|.
.|.|.|.|.|.|.|.|.|.|
|.|.|.|.|.|.|.|.|.|.
.|.|.|.|.|.|.|.|.|.|
|.|.|.|.|.|.|.|.|.|.
.|.|.|.|.|.|.|.|.|.T
2 7 7 20
*/

优先队列:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>using namespace std;char map[30][30];
int vis[30][30];
struct node
{int x,y,t;bool operator < (const node &a) const {return t>a.t;//最小值优先}
};
int dx[4]= {0,1,0,-1};//右,下,左,上
int dy[4]= {1,0,-1,0};
int n,m;
int sx,sy;int judge(int x,int y)
{if(x<0||x>=n||y<0||y>=m||map[x][y]=='*'||vis[x][y])return 0;return 1;
}int bfs()
{memset(vis,0,sizeof(vis));priority_queue<node> q;node ft;ft.x=sx;ft.y=sy;ft.t=0;vis[sx][sy]=1;q.push(ft);while(!q.empty()){ft = q.top();q.pop();if(map[ft.x][ft.y]=='T'){return ft.t;}for(int i=0; i<4; i++){node next;int nx=ft.x+dx[i];int ny=ft.y+dy[i];if(nx<0||nx>=n||ny<0||ny>=m){continue;}if(vis[nx][ny]||map[nx][ny]=='*'){continue;}else if(map[nx][ny]=='.'||map[nx][ny]=='T'){next.x=nx;next.y=ny;next.t=ft.t+1;vis[nx][ny]=1;q.push(next);}else{if(i==0||i==2)//右和左{//楼梯是横向,且走的时间为偶数if(map[nx][ny]=='-'&&ft.t%2==0){nx=nx+dx[i];ny=ny+dy[i];if(judge(nx,ny)){next.x=nx;next.y=ny;next.t=ft.t+1;vis[nx][ny]=1;q.push(next);}}else if(map[nx][ny]=='|'&&ft.t%2==1){//楼梯是竖向,且走的时间为奇数nx=nx+dx[i];ny=ny+dy[i];if(judge(nx,ny)){next.x=nx;next.y=ny;next.t=ft.t+1;vis[nx][ny]=1;q.push(next);}}else  //方向不对,需要等待一分钟{next.x=ft.x;next.y=ft.y;next.t=ft.t+1;q.push(next);}}else  //下上{if(map[nx][ny]=='-'&&ft.t%2==1){nx=nx+dx[i];ny=ny+dy[i];if(judge(nx,ny)){next.x=nx;next.y=ny;next.t=ft.t+1;vis[nx][ny]=1;q.push(next);}}else if(map[nx][ny]=='|'&&ft.t%2==0){nx=nx+dx[i];ny=ny+dy[i];if(judge(nx,ny)){next.x=nx;next.y=ny;next.t=ft.t+1;vis[nx][ny]=1;q.push(next);}}else  //方向不对,等待一分钟{next.x=ft.x;next.y=ft.y;next.t=ft.t+1;q.push(next);}}}}}return -1;
}int main()
{while(scanf("%d%d",&n,&m)!=EOF){for(int i=0; i<n; i++){scanf("%s",map[i]);for(int j=0; j<m; j++){if(map[i][j]=='S'){sx=i,sy=j;}}}printf("%d\n",bfs());}return 0;
}

HDOJ/HDU 1180 诡异的楼梯(经典BFS-详解)相关推荐

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

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

  2. HDU 1180 诡异的楼梯

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

  3. HDU 1180 诡异的楼梯

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

  4. hdu1180 诡异的楼梯(BFS+优先队列)

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

  5. 【算法设计与分析】HDU-1108 C++诡异的楼梯(BFS迷宫最短路径)

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

  6. UNIX经典命令详解

    UNIX经典命令详解 第一章 目录及文件操作命令 1.1 ls [语法]: ls [-RadCxmlnogrtucpFbqisf1] [目录或文件......]  [说明]: ls 命令列出指定目录下 ...

  7. Visual C++网络编程经典案例详解 第9章 实用播放器 数据读取与播放控制 识别数据文件信息

    识别数据文件信息主要是指对mp3数据格式识别 定义顺序代码如下 typedef struct mp3_struct //自定义mp3结构体 {char heade[3]; //tag字符标记char ...

  8. python 经典脚本文件_Python3.5文件读与写操作经典实例详解

    本文实例讲述了Python3.5文件读与写操作.分享给大家供大家参考,具体如下: 1.文件操作的基本流程: (1)打开文件,得到文件句柄并赋值给一个变量 (2)通过句柄对文件进行操作 (3)关闭文件 ...

  9. 经典算法详解--CART分类决策树、回归树和模型树

    Classification And Regression Tree(CART)是一种很重要的机器学习算法,既可以用于创建分类树(Classification Tree),也可以用于创建回归树(Reg ...

最新文章

  1. hdu 3666 THE MATRIX PROBLEM
  2. H3C交换机配置本地和远程登录用户名和密码
  3. DIV+CSS 网页布局之:三列布局
  4. 由java的八个基本数据类型说开去
  5. 【最详细】测试点分析_1051 复数乘法 (15分)_14行代码AC
  6. 学成在线--3.CMS页面管理开发(自定义条件查询)
  7. python中的索引从几开始计数_计算机为什么要从 0 开始计数?
  8. C++设计模式-Composite组合模式
  9. php css 编译,LAMP环境搭建之php安装
  10. 【自然框架】——重开在线演示
  11. php如何制作列表翻页,php 生成翻页链接(页码)列表的函数
  12. 面向对象编程已死,OOP 永存!
  13. Heritrix 3.1.0 源码解析(十四)
  14. mysql搜索结果去重_MySQL去除查询结果重复
  15. 如何使用 iMovie 为影片添加字幕、综艺字?
  16. 中国移动CMPP接口
  17. 用正则表达式验证邮箱和手机号
  18. 伤感的英文单词[转帖]
  19. 使用MagicIndicator+ViewPager2出现requestLayout() improperly called by
  20. Google adsense单价降低的原因-失误的无效点击过滤

热门文章

  1. C语言文本内容按照前四位用户编号排序
  2. Python基础知识的思维导图
  3. php擂台赛,清华校友擂台赛 尹祖江序盘失机 梁敬弘怒涛连胜
  4. Python 安装requests库
  5. 2024东华大学计算机考研信息汇总
  6. Python退出程序 sys.exit()
  7. 数字化“虚拟电厂”,精准管控助推节能减碳(一)
  8. 浅谈bluebird包的使用理解
  9. 使用mkldnn为cpu运行网络加速
  10. 半夜,滴滴司机问我会 LRU 吗?