http://acm.hdu.edu.cn/showproblem.php?pid=3085

出的很好的双向bfs,卡时间,普通的bfs会超时

题意方面:

1. 可停留

2. ghost无视墙壁

3. 需要检查两次某个地点是否有ghost,正要到达的时候(t),以及即将启程的时候(t+1).

在编程时需要注意的是:

当两个人汇合时,不需要检查即将启程的那次.

M可以走3步,在这3步中间只需要检查是否能到达(t)

出问题在: 1. 检查时间处理的不清晰

2.普通bfs会超时

3.双向bfs需要完全处理完某一时间,否则会出现

  a.女孩已经走完了程序自动退出(que[0].empty()&&!que[1].empty())

  b.因为女孩的步数比较多不是最优解的情况

  1. #include <cstdio>
  2. #include <algorithm>
  3. #include <queue>
  4. using namespace std;
  5. const int inf =0x3fffffff;
  6. const int maxn=1e3+3;
  7. char maz[maxn][maxn];
  8. int n,m;
  9. struct pnt
  10. {
  11. int x,y;
  12. pnt()
  13. {
  14. x=y=0;
  15. }
  16. pnt(int tx,int ty):x(tx),y(ty) {}
  17. } z[2],b,g;
  18. typedef pair<pnt,int> P;
  19. int zn;
  20.  
  21. bool ok(int x,int y,int time)
  22. {
  23. for(int i=0; i<2; i++)
  24. {
  25. int h=abs(x-z[i].x)+abs(y-z[i].y);
  26. if(h<=2*time)
  27. {
  28. return false;
  29. }
  30. }
  31. return true;
  32. }
  33.  
  34. int dg[maxn][maxn],db[maxn][maxn];
  35. queue<pnt> que[2];
  36. const int dx[4]= {1,-1,0,0};
  37. const int dy[4]= {0,0,1,-1};
  38. bool in(int x,int y)
  39. {
  40. return x>=0&&x<n&&y>=0&&y<m&&maz[x][y]!='X';
  41. }
  42. int tempt(int step,int s,int cnt)
  43. {
  44. int sz=que[s].size();
  45. while(sz--)
  46. {
  47. pnt f=que[s].front();que[s].pop();
  48. if(!ok(f.x,f.y,step))continue;
  49. for(int di=0; di<4; di++)
  50. {
  51. pnt t=pnt(f.x+dx[di],f.y+dy[di]);
  52. if(in(t.x,t.y)&&ok(t.x,t.y,step))
  53. {
  54. if(s)
  55. {
  56. if(db[t.x][t.y]>step)
  57. {
  58. db[t.x][t.y]=step;
  59. if(dg[t.x][t.y]!=inf)
  60. return step;
  61. que[s].push(t);
  62. }
  63. }
  64. else
  65. {
  66. if(dg[t.x][t.y]>step)
  67. {
  68. dg[t.x][t.y]=step;
  69. if(db[t.x][t.y]!=inf)
  70. return step;
  71. que[s].push(t);
  72. }
  73. }
  74. }
  75. }
  76. }
  77. return -1;
  78. }
  79.  
  80. int bfs()
  81. {
  82. while(!que[0].empty())que[0].pop();
  83. while(!que[1].empty())que[1].pop();
  84.  
  85. que[0].push(g);
  86. que[1].push(b);
  87. int step=0;
  88. while(!que[0].empty()&&!que[1].empty())
  89. {
  90. step++;
  91. int tmp;
  92. if((tmp=tempt(step,0,0))!=-1)return tmp;
  93. if((tmp=tempt(step,1,1))!=-1)return tmp;
  94. if((tmp=tempt(step,1,2))!=-1)return tmp;
  95. if((tmp=tempt(step,1,3))!=-1)return tmp;
  96. }
  97. return -1;
  98. }
  99.  
  100. void init()
  101. {
  102. zn=0;
  103. for(int i=0; i<n; i++)fill(dg[i],dg[i]+m,inf);
  104. for(int i=0; i<n; i++)fill(db[i],db[i]+m,inf);
  105. }
  106. int main()
  107. {
  108. int T;
  109. scanf("%d",&T);
  110. for(int ti=1; ti<=T; ti++)
  111. {
  112. scanf("%d%d",&n,&m);
  113. init();
  114. for(int i=0; i<n; i++)
  115. {
  116. scanf("%s",maz[i]);
  117. for(int j=0; j<m; j++)
  118. {
  119. if(maz[i][j]=='Z')
  120. {
  121. z[zn++]=pnt(i,j);
  122. }
  123. else if(maz[i][j]=='G')
  124. {
  125. g=pnt(i,j);
  126. dg[g.x][g.y]=0;
  127. }
  128. else if(maz[i][j]=='M')
  129. {
  130. b=pnt(i,j);
  131. db[b.x][b.y]=0;
  132. }
  133. }
  134. }
  135. int ans=bfs();
  136. printf("%d\n",ans);
  137. }
  138. return 0;
  139. }

HDU 3085 Nightmare II 双向bfs 难度:2的更多相关文章

  1. HDU 3085 Nightmare Ⅱ(双向BFS)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3085 题目大意:给你一张n*m地图上,上面有有 ‘. ’:路 ‘X':墙 ’Z':鬼,每秒移动2步,可 ...

  2. HDOJ3085 Nightmare II 双向BFS

    重构一遍就A了...但这样效率太低了...莫非都要重构???QWQ 每一秒男同志bfs3层,女同志bfs1层.注意扩展状态时,要判一下合不合法再扩展,而不是只判扩展的状态合不合法,否则有可能由非法的走 ...

  3. HDU 3085 Nightmare Ⅱ(噩梦 Ⅱ)

    HDU 3085 Nightmare Ⅱ(噩梦 Ⅱ) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Ja ...

  4. HDU - 3085 Nightmare Ⅱ

    HDU - 3085 Nightmare Ⅱ 双向BFS,建立两个队列,让男孩女孩一起走 鬼的位置用曼哈顿距离判断一下,如果该位置与鬼的曼哈顿距离小于等于当前轮数的两倍,则已经被鬼覆盖 #includ ...

  5. HDU 3085 Nightmare Ⅱ (双向BFS)

    Nightmare Ⅱ Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  6. HDU 3085 Nightmare Ⅱ 双向BFS

    题意:很好理解,然后注意几点,男的可以一秒走三步,也就是三步以内的都可以,鬼可以穿墙,但是人不可以,鬼是一次走两步 分析:我刚开始男女,鬼BFS三遍,然后最后处理答案,严重超时,然后上网看题解,发现是 ...

  7. HDU 1043 Eight(双向BFS+康托展开)

    http://acm.hdu.edu.cn/showproblem.php?pid=1043 题意:给出一个八数码,求出到达指定状态的路径. 思路:路径寻找问题.在这道题里用到的知识点挺多的.第一次用 ...

  8. Nightmare Ⅱ(双向BFS)

    Problem Description Last night, little erriyue had a horrible nightmare. He dreamed that he and his ...

  9. HDU 6171 Admiral(双向BFS+队列)题解

    思路: 最大步骤有20,直接BFS会超时. 因为知道开始情况和结果所以可以用双向BFS,每个BFS规定最大步骤为10,这样相加肯定小于20.这里要保存每个状态搜索到的最小步骤,用Hash储存.当发现现 ...

随机推荐

  1. 巴科斯范式和sql语言

    查询Mysql帮助文档,如何写SQL语句的时候,需要注意SQL语法,这里就需要知道BNF巴科斯范式. 巴科斯范式:BNF用于描述计算机语言.基本的规则如下: 尖括号<> 内包含的为必选项. ...

  2. Android linearlayout常用布局

    用linearlayout完成这样的布局效果,这样的布局还是比较常用的,具体的xml代码如下: <LinearLayout xmlns:android="http://schemas. ...

  3. Python学习笔记16—电子表格

    openpyl 模块是解决 Microsoft Excel 2007/2010 之类版本中扩展名是 Excel 2010 xlsx/xlsm/xltx/xltm 的文件的读写的第三方库. 安装 pip ...

  4. 转自“脚本之家”!!JDBC之PreparedStatement类中预编译的综合应用解析

    JDK 文档:SQL 语句被预编译并存储在 PreparedStatement 对象中(PreparedStatement是存储在JDBC里的,初始化后,缓存到了JDBC里),然后可以使用此对象多次高 ...

  5. commonJS — 对象操作(for Object)

    for Object github: https://github.com/laixiangran/commonJS/blob/master/src/forObject.js 代码 /** * Cre ...

  6. drupal 2016-11-3

    我随意定义了一个hook menu发现里面的内容很快就加入到了navigation menu里面.

  7. xcode 脚本编译,打包ipa

    1.清理工程 /usr/bin/xcodebuild -target targetName clean 2.编译 /usr/bin/xcodebuild -target targetName buil ...

  8. phalcon: 获取参数的方法

    phalcon: 获取参数的方法 一般情况下:GET/POST $this->request->get(参数); $this->request->getPost("参 ...

  9. VB6 GDI+ 入门教程[6] 图片

    http://vistaswx.com/blog/article/category/tutorial/page/2 VB6 GDI+ 入门教程[6] 图片 2009 年 6 月 19 日 15条评论 ...

  10. Selenium解决页面元素不在视野范围内的问题

    当需要使用滚动条才能使页面元素显示在视野范围内时,必须用代码处理下,才能对其进行操作. 处理其实也很简单,就是调用JS函数. driver.executeScript("arguments[ ...