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

  1. 5 5
  2. **..T
  3. **.*.
  4. ..|..
  5. .*.*.
  6. S....

Sample Output

7

Hint

Hint

地图如下:

挺经典的一个广搜题目!

题意很好理解。做的时候理清思路,注意楼梯的方向,楼梯的方向可以用到达时候的时间的奇偶来判断。因为楼梯只有2个方向!上下,或者左右。

移动到楼梯后面也还要判断下是否越界,楼梯对面是不是墙,是不是已经走过,这3个条件,满足了才能过去。

如果到的时候,楼梯方向与过去的方向不同,就只能等待一分钟,在这个时候,位置不动,时间加1!再进入队列。这个顺序很重要!

不能先过去,然后时间加2,再入队列。这样会超内存,这是很多人用优先队列的原因!

(因为这样的话,你会发现,弹出的node型变量的t会出现t-时间小的会在后面弹出,这样增加了内存的使用!!!)

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <queue>
  5. using namespace std;
  6. struct node{
  7. int x,y,t;
  8. };
  9. int n,m;
  10. int mx[]={0,1,0,-1};
  11. int my[]={1,0,-1,0};//右,下,左,上
  12. char map[30][30];
  13. int d[30][30];
  14. int tx,ty,sx,sy;
  15. node ft;
  16. int judge(int x,int y){
  17. if(x<0||x>=n||y<0||y>=m){
  18. return 0;
  19. }
  20. if(d[x][y]){
  21. return 0;
  22. }
  23. if(map[x][y]=='*'){
  24. return 0;
  25. }
  26. return 1;
  27. }
  28. void bfs(){
  29. queue<node> q;
  30. ft.x=sx;
  31. ft.y=sy;
  32. ft.t=0;
  33. q.push(ft);
  34. d[sx][sy]=1;
  35. while(!q.empty()){
  36. node ff=q.front();
  37. q.pop();
  38. int x=ff.x;
  39. int y=ff.y;
  40. if(map[x][y]=='T'){
  41. printf("%d\n",ff.t);
  42. return;
  43. }
  44. for(int i=0;i<4;i++){
  45. x=ff.x+mx[i];
  46. y=ff.y+my[i];
  47. if(!judge(x,y)){
  48. continue;
  49. }
  50. node nt;
  51. if(map[x][y]=='.'||map[x][y]=='T'){//正常走
  52. nt.x=x;
  53. nt.y=y;
  54. nt.t=ff.t+1;
  55. d[nt.x][nt.y]=1;
  56. q.push(nt);
  57. continue;
  58. }else if(i==0||i==2){//右和左
  59. if(map[x][y]=='-'&&ff.t%2==0){//可以过去
  60. nt.x=x+mx[i];
  61. nt.y=y+my[i];
  62. if(judge(nt.x,nt.y)){
  63. nt.t=ff.t+1;
  64. d[nt.x][nt.y]=1;
  65. q.push(nt);
  66. }
  67. }else if(map[x][y]=='|'&&ff.t%2!=0){
  68. nt.x=x+mx[i];
  69. nt.y=y+my[i];
  70. if(judge(nt.x,nt.y)){
  71. nt.t=ff.t+1;
  72. d[nt.x][nt.y]=1;
  73. q.push(nt);
  74. }
  75. }else {//不能过楼梯,得等一分钟
  76. nt.x=ff.x;
  77. nt.y=ff.y;
  78. nt.t=ff.t+1;
  79. d[nt.x][nt.y]=1;
  80. q.push(nt);
  81. }
  82. }else{//上和下
  83. if(map[x][y]=='|'&&ff.t%2==0){//可以过去
  84. nt.x=x+mx[i];
  85. nt.y=y+my[i];
  86. if(judge(nt.x,nt.y)){
  87. nt.t=ff.t+1;
  88. d[nt.x][nt.y]=1;
  89. q.push(nt);
  90. }
  91. }else if(map[x][y]=='-'&&ff.t%2!=0){
  92. nt.x=x+mx[i];
  93. nt.y=y+my[i];
  94. if(judge(nt.x,nt.y)){
  95. nt.t=ff.t+1;
  96. d[nt.x][nt.y]=1;
  97. q.push(nt);
  98. }
  99. }else {//不能过楼梯,得等一分钟
  100. nt.x=ff.x;
  101. nt.y=ff.y;
  102. nt.t=ff.t+1;
  103. d[nt.x][nt.y]=1;
  104. q.push(nt);
  105. }
  106. }
  107. }
  108. }
  109. }
  110. int main(){
  111. while(~scanf("%d%d",&n,&m)){
  112. memset(d,0,sizeof(d));
  113. for(int i=0;i<n;i++){
  114. scanf("%s",map[i]);
  115. for(int j=0;j<m;j++){
  116. if(map[i][j]=='S'){
  117. sx=i,sy=j;
  118. }
  119. }
  120. }
  121. bfs();
  122. }
  123. return 0;
  124. }
  125. 测试数据:
  126. /*
  127. 3 3
  128. S|.
  129. -..
  130. T..
  131. 5 5
  132. **..T
  133. **.*.
  134. ..|..
  135. .*.*.
  136. S....
  137. 3 4
  138. S|.|
  139. -T-.
  140. .|..
  141. 20 20
  142. S.|.|.|.|.|.|.|.|.|.
  143. .|.|.|.|.|.|.|.|.|.|
  144. |.|.|.|.|.|.|.|.|.|.
  145. .|.|.|.|.|.|.|.|.|.|
  146. |.|.|.|.|.|.|.|.|.|.
  147. .|.|.|.|.|.|.|.|.|.|
  148. |.|.|.|.|.|.|.|.|.|.
  149. .|.|.|.|.|.|.|.|.|.|
  150. |.|.|.|.|.|.|.|.|.|.
  151. .|.|.|.|.|.|.|.|.|.|
  152. |.|.|.|.|.|.|.|.|.|.
  153. .|.|.|.|.|.|.|.|.|.|
  154. |.|.|.|.|.|.|.|.|.|.
  155. .|.|.|.|.|.|.|.|.|.|
  156. |.|.|.|.|.|.|.|.|.|.
  157. .|.|.|.|.|.|.|.|.|.|
  158. |.|.|.|.|.|.|.|.|.|.
  159. .|.|.|.|.|.|.|.|.|.|
  160. |.|.|.|.|.|.|.|.|.|.
  161. .|.|.|.|.|.|.|.|.|.T
  162. 2 7 7 20
  163. */

优先队列:

  1. #include <iostream>
  2. #include <cstring>
  3. #include <cstdio>
  4. #include <queue>
  5. using namespace std;
  6. char map[30][30];
  7. int vis[30][30];
  8. struct node
  9. {
  10. int x,y,t;
  11. bool operator < (const node &a) const {
  12. return t>a.t;//最小值优先
  13. }
  14. };
  15. int dx[4]= {0,1,0,-1};//右,下,左,上
  16. int dy[4]= {1,0,-1,0};
  17. int n,m;
  18. int sx,sy;
  19. int judge(int x,int y)
  20. {
  21. if(x<0||x>=n||y<0||y>=m||map[x][y]=='*'||vis[x][y])
  22. return 0;
  23. return 1;
  24. }
  25. int bfs()
  26. {
  27. memset(vis,0,sizeof(vis));
  28. priority_queue<node> q;
  29. node ft;
  30. ft.x=sx;
  31. ft.y=sy;
  32. ft.t=0;
  33. vis[sx][sy]=1;
  34. q.push(ft);
  35. while(!q.empty())
  36. {
  37. ft = q.top();
  38. q.pop();
  39. if(map[ft.x][ft.y]=='T')
  40. {
  41. return ft.t;
  42. }
  43. for(int i=0; i<4; i++)
  44. {
  45. node next;
  46. int nx=ft.x+dx[i];
  47. int ny=ft.y+dy[i];
  48. if(nx<0||nx>=n||ny<0||ny>=m)
  49. {
  50. continue;
  51. }
  52. if(vis[nx][ny]||map[nx][ny]=='*')
  53. {
  54. continue;
  55. }else if(map[nx][ny]=='.'||map[nx][ny]=='T')
  56. {
  57. next.x=nx;
  58. next.y=ny;
  59. next.t=ft.t+1;
  60. vis[nx][ny]=1;
  61. q.push(next);
  62. }
  63. else
  64. {
  65. if(i==0||i==2)//右和左
  66. {
  67. //楼梯是横向,且走的时间为偶数
  68. if(map[nx][ny]=='-'&&ft.t%2==0)
  69. {
  70. nx=nx+dx[i];
  71. ny=ny+dy[i];
  72. if(judge(nx,ny))
  73. {
  74. next.x=nx;
  75. next.y=ny;
  76. next.t=ft.t+1;
  77. vis[nx][ny]=1;
  78. q.push(next);
  79. }
  80. }
  81. else if(map[nx][ny]=='|'&&ft.t%2==1)
  82. {
  83. //楼梯是竖向,且走的时间为奇数
  84. nx=nx+dx[i];
  85. ny=ny+dy[i];
  86. if(judge(nx,ny))
  87. {
  88. next.x=nx;
  89. next.y=ny;
  90. next.t=ft.t+1;
  91. vis[nx][ny]=1;
  92. q.push(next);
  93. }
  94. }
  95. else //方向不对,需要等待一分钟
  96. {
  97. next.x=ft.x;
  98. next.y=ft.y;
  99. next.t=ft.t+1;
  100. q.push(next);
  101. }
  102. }
  103. else //下上
  104. {
  105. if(map[nx][ny]=='-'&&ft.t%2==1)
  106. {
  107. nx=nx+dx[i];
  108. ny=ny+dy[i];
  109. if(judge(nx,ny))
  110. {
  111. next.x=nx;
  112. next.y=ny;
  113. next.t=ft.t+1;
  114. vis[nx][ny]=1;
  115. q.push(next);
  116. }
  117. }
  118. else if(map[nx][ny]=='|'&&ft.t%2==0)
  119. {
  120. nx=nx+dx[i];
  121. ny=ny+dy[i];
  122. if(judge(nx,ny))
  123. {
  124. next.x=nx;
  125. next.y=ny;
  126. next.t=ft.t+1;
  127. vis[nx][ny]=1;
  128. q.push(next);
  129. }
  130. }
  131. else //方向不对,等待一分钟
  132. {
  133. next.x=ft.x;
  134. next.y=ft.y;
  135. next.t=ft.t+1;
  136. q.push(next);
  137. }
  138. }
  139. }
  140. }
  141. }
  142. return -1;
  143. }
  144. int main()
  145. {
  146. while(scanf("%d%d",&n,&m)!=EOF)
  147. {
  148. for(int i=0; i<n; i++)
  149. {
  150. scanf("%s",map[i]);
  151. for(int j=0; j<m; j++)
  152. {
  153. if(map[i][j]=='S')
  154. {
  155. sx=i,sy=j;
  156. }
  157. }
  158. }
  159. printf("%d\n",bfs());
  160. }
  161. return 0;
  162. }

HDOJ/HDU 1180 诡异的楼梯(经典BFS-详解)的更多相关文章

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

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

  2. hdu 1180:诡异的楼梯(BFS广搜)

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

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

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

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

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

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

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

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

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

  7. hdu 1180 诡异的楼梯

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

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

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

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

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

随机推荐

  1. layerX && layerY

    转载:https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/layerX UIEvent.layerX 非标准 这个属性是非标准的属性,并且 ...

  2. leetcode problem 10 Regular Expression Matching(动态规划)

    Implement regular expression matching with support for '.' and '*'. '.' Matches any single character ...

  3. Ubuntu 之旅—— 调整扩展屏分辨率

    打开终端输入 xrandr 得到如下信息 Screen 0: minimum 320 x 200, current 2390 x 768, maximum 8192 x 8192 LVDS conne ...

  4. write() ,read();

    int main1(int argc ,char *argv[]){ if(argc < 2 ) return 0; int fd = open(argv[1] , O_RDONLY); if( ...

  5. datareader 和dataset 区别

    ADO.NET2.0提供了两个用于检索关系数据的对象:DataSet和DataReader.并且这两个对象都可以将检索的关系数据存储在内存中.在软件开发过程中经常用到这两个控件,由于这两个控件在使用和 ...

  6. sae后台管理端的js,daterangepicker使用

    原本只为了日期范围选择器看下sae的前端怎么实现 然后... 公共函数两个文件,第一个是各种插件: typeahead.js 自动完成 //关键词自动完成 $('#page-auto-complete ...

  7. overflow:hidden真的失效了吗

    项目中常常有同学遇到这样的问题,现象是给元素设置了overflow:hidden,但超出容器的部分并没有被隐藏,难道是设置的hidden失效了吗? 其实看似不合理的现象背后都会有其合理的解释. 我们知 ...

  8. 小笔记(二):php数组

    一.对于一二维数组重新组合为另一个二维数组,根据键值名称对一个二维数组进行重新组合例: /*$paramArray=array( * 'a'=>array('0'=>'1','1'=> ...

  9. wampserver修改默认根目录

    1.打开wamp/scripts/config.inc.php ,修改$wwwDir = $c_installDir.’/www’; 2.打开wamp/bin/apache/apache2.4.9/c ...

  10. POJ 1442 Black Box 堆

    题目: http://poj.org/problem?id=1442 开始用二叉排序树写的,TLE了,改成优先队列,过了.. 两个版本都贴一下吧,赚稿费.. #include <stdio.h& ...