当前位置: 代码迷 >> 综合 >> hdoj1010 Tempter of the Bone(DFS迷宫)在规定时间内刚好到达
  详细解决方案

hdoj1010 Tempter of the Bone(DFS迷宫)在规定时间内刚好到达

热度:16   发布时间:2023-12-14 01:14:56.0

题目链接:

hdoj1010

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

题意:给出一个n*m的迷宫和时间t,图中X表示墙不能走过,S表示起点,D表示门,.表示可以走的路。每走一步需要1s,从S到D的时间不能大于t,也不能小于t,只能刚好等于t,不能回过头走重复的路,因为走完的路在1s之内就会塌陷,如果能够在规定时间刚好到达出口,则输出YES,否则就输出NO。
思路:先用字符二维数组a存迷宫,想好终止条件count > t和此时访问的刚好是D并且走过的时间刚好等于规定的时间,用一个success来标记有没有成功找到出口,如果在此时刚好访问到D并且走过的时间刚好等于规定的时间就标记success=true。在当前经历上为S或者.的时候,就将flag[sx][sy]标记为1,然后分别预测下一步是什么如果不超过数组范围并且没有访问过的话,就递归再深搜,这些条件写好后再回溯标记flag[sx][sy]为0,标记为未访问过,因为该点可以有多条路径经过,其实就是在枚举路径。

#include<iostream>
#include<cstdio>
#include<stack> 
#include<queue>
#include<vector>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<set>
#include<map>using namespace std;char a[10][10];
int n,m,t;
int x,y;
int flag[10][10] = {
    0};
bool success;void dfs(int sx,int sy,int count) {
    if(count > t) {
    return;} else if(a[sx][sy] == 'D' && count == t) {
    success = true;return;} else if(a[sx][sy] == 'S' || a[sx][sy] == '.') {
    flag[sx][sy] = 1;
// cout << sx << sy << endl; if(sy + 1 < m && flag[sx][sy + 1] == 0) dfs(sx,sy + 1,count + 1); //向右走一步 if(sy - 1 >= 0 && flag[sx][sy - 1] == 0) dfs(sx,sy - 1,count + 1); //向左走一步 if(sx + 1 < n && flag[sx + 1][sy] == 0) dfs(sx + 1,sy,count + 1); //向下走一步 if(sx - 1 >= 0 && flag[sx - 1][sy] == 0) dfs(sx - 1,sy,count + 1); //向上走一步 flag[sx][sy] = 0;}
}int main() {
    while(~scanf("%d%d%d",&n,&m,&t) && (m + n + t)) {
    for(int i = 0;i < n;i++) {
    for(int j = 0;j < m;j++) {
    cin >> a[i][j];}}success = false;for(int i = 0;i < n;i++) {
    for(int j = 0;j < m;j++) {
    flag[i][j] = 0;if(a[i][j] == 'S') {
    x = i;y = j;			}}}dfs(x,y,0);if(success) {
    printf("YES\n");} else {
    printf("NO\n");}}return 0;
}