1)   题目

Tempter of the Bone

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 47967    Accepted Submission(s): 12905

Problem Description

The doggie found a bone in an ancient maze, which fascinated him a lot. However, when he picked it up, the maze began to shake, and the doggie could feel the ground sinking. He realized that the bone was a trap, and he tried desperately to get out of this maze.

The maze was a rectangle with sizes N by M. There was a door in the maze. At the beginning, the door was closed and it would open at the T-th second for a short period of time (less than 1 second). Therefore the doggie had to arrive at the door on exactly the T-th second. In every second, he could move one block to one of the upper, lower, left and right neighboring blocks. Once he entered a block, the ground of this block would start to sink and disappear in the next second. He could not stay at one block for more than one second, nor could he move into a visited block. Can the poor doggie survive? Please help him.

Input

The input consists of multiple test cases. The first line of each test case contains three integers N, M, and T (1 < N, M < 7; 0 < T < 50), which denote the sizes of the maze and the time at which the door will open, respectively. The next N lines give the maze layout, with each line containing M characters. A character is one of the following:

'X': a block of wall, which the doggie cannot enter; 
'S': the start point of the doggie; 
'D': the Door; or
'.': an empty block.

The input is terminated with three 0's. This test case is not to be processed.

Output

For each test case, print in one line "YES" if the doggie can survive, or "NO" otherwise.

Sample Input

4 4 5
S.X.
..X.
..XD
....
3 4 5
S.X.
..X.
...D
0 0 0

Sample Output

NO
YES

 

2)    题意

在一个n行m列的迷宫中,每一步只能向上、下、左、右中任意方向走一格,迷宫中有围墙的地方是无法到达的。从起点s开始,能否刚好走t步,到达e。

3)    数据范围

迷宫大小最大为6*6,测试数据组数最大为50组。感觉上数据量很小,可实际上,如果在6*6的迷宫中,枚举所有可能路径的话,时间复杂度是指数级的,所以剪枝是关键。

4)    算法

先用BFS判断s到e是否有路径,以及这条最短路径长度是否小于等于t,然后再进行回溯法+奇偶剪枝。

迷宫中回溯法的剪枝——奇偶剪枝

5)    代码

[cpp] view plaincopyprint?
  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <queue>
  5. using namespace std;
  6. #define MAXSIZE 10
  7. int dir[4][2] = {-1, 0, 0, 1, 1, 0, 0, -1};
  8. char maze[MAXSIZE][MAXSIZE];
  9. bool vis[MAXSIZE][MAXSIZE];
  10. int dx, dy;
  11. bool finished;
  12. void InitMaze(int m, int n)
  13. {
  14. int i;
  15. for (i = 0; i < m+2; i++)
  16. {
  17. maze[i][0] = maze[i][n+1] = 'X';
  18. }
  19. for (i = 0; i < n+2; i++)
  20. {
  21. maze[0][i] = maze[m+1][i] = 'X';
  22. }
  23. }
  24. void Backtrack(int x, int y, int rt)
  25. {
  26. vis[x][y] = true;
  27. if (x == dx && y == dy)
  28. {
  29. if (rt == 0)
  30. {
  31. finished = true;
  32. }
  33. }
  34. else
  35. {
  36. int i;
  37. for (i = 0; i < 4; i++)
  38. {
  39. int nextx = x + dir[i][0];
  40. int nexty = y + dir[i][1];
  41. if (!vis[nextx][nexty] && maze[nextx][nexty] != 'X')
  42. {
  43. Backtrack(nextx, nexty, rt-1);
  44. if (finished)
  45. {
  46. return;
  47. }
  48. }
  49. }
  50. }
  51. vis[x][y] = false;
  52. }
  53. struct Position
  54. {
  55. int x, y;
  56. int nsteps;
  57. };
  58. int BFS(int x, int y)
  59. {
  60. queue<Position> next;
  61. Position currPos = {x, y, 0};
  62. next.push(currPos);
  63. vis[x][y] = true;
  64. while (!next.empty())
  65. {
  66. currPos = next.front();
  67. next.pop();
  68. if (currPos.x == dx && currPos.y == dy)
  69. {
  70. return currPos.nsteps;
  71. }
  72. int i;
  73. for (i = 0; i < 4; i++)
  74. {
  75. Position nextPos = currPos;
  76. nextPos.x += dir[i][0];
  77. nextPos.y += dir[i][1];
  78. if (!vis[nextPos.x][nextPos.y] && maze[nextPos.x][nextPos.y] != 'X')
  79. {
  80. nextPos.nsteps++;
  81. next.push(nextPos);
  82. vis[nextPos.x][nextPos.y] = true;
  83. }
  84. }
  85. }
  86. return -1;
  87. }
  88. int Dist(int x, int y)
  89. {
  90. return abs(dx-x)+abs(dy-y);
  91. }
  92. int main(void)
  93. {
  94. int m, n, t;
  95. while (scanf("%d%d%d", &m, &n, &t) != EOF)
  96. {
  97. getchar();
  98. if (m == 0 && n == 0 && t == 0)
  99. {
  100. break;
  101. }
  102. InitMaze(m, n);
  103. int sx, sy;
  104. int i, j;
  105. for (i = 1; i <= m; i++)
  106. {
  107. for (j = 1; j <= n; j++)
  108. {
  109. maze[i][j] = getchar();
  110. if (maze[i][j] == 'S')
  111. {
  112. sx = i;
  113. sy = j;
  114. }
  115. if (maze[i][j] == 'D')
  116. {
  117. dx = i;
  118. dy = j;
  119. }
  120. }
  121. getchar();
  122. }
  123. finished = false;
  124. if (Dist(sx, sy) % 2 == t % 2) //奇偶剪枝
  125. {
  126. memset(vis, false, sizeof(vis));
  127. int minNSteps = BFS(sx, sy);
  128. if (minNSteps != -1 && minNSteps <= t)
  129. {
  130. memset(vis, false, sizeof(vis));
  131. Backtrack(sx, sy, t);
  132. }
  133. }
  134. if (finished)
  135. {
  136. puts("YES");
  137. }
  138. else
  139. {
  140. puts("NO");
  141. }
  142. }
  143. return 0;
  144. }

6)    测试数据

4 4 5

S.X.

..X.

..XD

....

3 4 5

S.X.

..X.

...D

5 5 9

...D.

X.XX.

.XX..

SX...

....X

7)    提交结果

回溯法+奇偶剪枝——Hdu 1010 Tempter of the Bone相关推荐

  1. HDU.1010 Tempter of the Bone

    文章目录 一.题目解读 1.原题 2.分类 3.题意 4.输入输出格式 5.数据范围 二.题解参考 1.总体思路 2.思路① (1).分析 (2).AC代码 三.评价与后话 1.评价 2.奇偶剪枝0- ...

  2. HDU 1010 Tempter of the Bone heuristic 剪枝法

    本题就是考剪枝法了. 应该说是比较高级的应用了.因为要使用heuristic(经验)剪枝法.要总结出这个经验规律来,不容易.我说这是高级的应用也因为网上太多解题报告都没有分析好这题,给出的程序也很慢, ...

  3. HDOJ 1010 HDU 1010 Tempter of the Bone ACM 1010 IN HDU

    MiYu原创, 转帖请注明 : 转载自 ______________白白の屋 题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=1010 题目描述: 代码 ...

  4. HDU 1010 Tempter of the Bone heuristic 修剪

    的问题是,在测试修剪. 应该说是更先进的应用. 由于使用的heuristic(经验)修剪.总结这方面的经验法则,别easy.我说,这也是由于先进的在线报告中的应用程序没有分析太多太好的解决这个问题,计 ...

  5. HDU 1010 Tempter of the Bone DFS(奇偶剪枝优化)

    需要剪枝否则会超时,然后就是基本的深搜了 #include<cstdio> #include<stdio.h> #include<cstdlib> #include ...

  6. 输入空格hdu - 1010 - Tempter of the Bone

    时间紧张,先记一笔,后续优化与完善. 题意:一个N*M的地图,走过的点不能再走,X为墙弗成走,能否从点S到点D恰好用时T.(1 < N, M < 7; 0 < T < 50) ...

  7. (step4.3.1) hdu 1010(Tempter of the Bone——DFS)

    题目大意:输入三个整数N,M,T.在接下来的N行.M列会有一系列的字符.其中S表示起点,D表示终点. .表示路 . X表示墙...问狗能有在T秒时到达D.如果能输出YES, 否则输出NO 解题思路:D ...

  8. DFS 如何避免重复母题 Leetcode 077组合(人为规定选取顺序:本题为只能从前往后选,好马不吃回头草)(类似题:Leetcode047全排列(可能含重复元素)-回溯法加剪枝)

    类似题 Leetcode047全排列(可能含重复元素)-----------回溯法加剪枝 https://blog.csdn.net/qq_52934831/article/details/11957 ...

  9. 【算法学习笔记】16.暴力求解法04 回溯法03 剪枝法 带宽

    在之前的 N 皇后和困难的串问题中,回溯法都是在解决可行性约束.换一句话说,对于回溯点的判断是用来验证此点是否合法. 但是在一些优化问题的求解过程中,每一个点都是合法的,所以我们要进行剪枝. 1.先得 ...

最新文章

  1. i基准指令集 mips_mips addiu
  2. C/C++语言中计算int,float,double,char四种数据类型所能表示的数据范围
  3. 史上最强翻译器,没有之一,不接受反驳
  4. Unity3D 深度图
  5. 使用 HTMLTestRunner.py
  6. ln -s 的一个坑
  7. 是无数像老钟叔的p8u8
  8. Win10 20H2正式发布,对比旧版新功能一览
  9. linux下最好的ftp服务器,用Linux系统构建高效FTP服务器
  10. C#的Timer解析
  11. 给一张表加一个自动编号字段_Python办公自动化|从Word到Excel
  12. xiao zhang   jia you
  13. Flash安装低版本方法
  14. CMD编写bat病毒
  15. file_contexts 踩坑
  16. 计算机网络知识点汇总(王道)
  17. kindle书籍的后缀名_kindle可以看什么格式
  18. 使用bibmap修改bib文件中参考文献的期刊或会议名的字母大小写格式为titlecase
  19. android fastboot 刷机教程,已进入fastboot怎么刷机教程
  20. 多肽TAT接枝/功能肽RGDC修饰荧光碳量子点/碳量子点修饰多肽LyP-1的制备研究

热门文章

  1. bzoj 1863 二分+dp check
  2. PHP HashTable总结
  3. JSP/Servlet Web 学习笔记 DayFour —— 实现一个简单的JSP/Servlet交互
  4. 用SNMP实现对大型网络的轻松管理!
  5. 应用SilverLight 2.0 BETA 2的 支持回调的在线聊天室(二)
  6. fork()与pid
  7. LeetCode算法题6:滑动窗口*
  8. 云端能力知几许?12人众测华为云企业级Kubernetes集群实力
  9. 开发一个自己的 CSS 框架(二)
  10. C语言学习 - 字节对齐