1 //hdu 1010 DFS + 剪枝
2
3 //这题意思是一只dog在迷宫中要走到出口,且出口只有在一个时间点
4 //会打开,要在这个时间点刚好到出口输出YES,如果不能逃出则输出NO
5 //走过的路会陷下去,也就是不能重复走,X表示墙,不能走
6 //这题主要就是剪枝,我的代码在三个地方剪枝
7 //1: dog走的步数超过开门的时间就return
8 //2: 输入时累加可以走的点数,如果可走的点都比规定的时间还少,直接输出NO
9 //3: 奇偶剪枝,起点 到 终点 的步数的奇偶性和限制时间的奇偶性要相同
10 // 才可能到达
11
12
13 #include <stdio.h>
14 #include <string.h>
15 #include <stdlib.h>
16
17 #define N 10
18
19 int row, col, time, dog_x, dog_y, door_x, door_y;
20 bool out;
21 char maze[N][N];
22
23
24 //设置四个方向,上 左 下 右
25 int dir_x[4] ={-1, 0, 1, 0}, dir_y[4] = {0, -1, 0, 1};
26
27 void dfs(int x, int y, int step)
28 {
29 if(out == true)
30 return;
31
32 //如果到了门的地方且门刚好开着
33 if(x == door_x && y == door_y && step == time)
34 {
35 out = true; //标记找到答案
36 return;
37 }
38 //剩下的步数不能到达终点,则返回
39 if(step + abs(x - door_x) + abs(y - door_y) > time)
40 return;
41
42 for(int i = 0; i < 4; ++i) //下一步的4 个方向
43 {
44 if(out == true) //若已经得到能逃出maze 就返回
45 return;
46 //下一步的 坐标
47 int next_x = x + dir_x[i], next_y = y + dir_y[i];
48
49 //如果越界了,则尝试别的方向
50 if(next_x < 0 || next_x >= row || next_y < 0 || next_y >= col)
51 continue;
52
53 if(maze[next_x][next_y] != 'X')
54 {
55 maze[next_x][next_y] = 'X'; //走过了标记为不可再走
56 dfs(next_x, next_y, step+1);//继续往下搜
57 maze[next_x][next_y] = '.'; //回溯后标记回来
58 }
59 }
60 }
61
62 int main()
63 {
64 //freopen("in.txt", "r", stdin);
65 while(scanf("%d%d%d%*c", &row, &col, &time), row||col||time)
66 {
67 int num = 0;
68 for(int i = 0; i < row; ++i)
69 {
70 for(int j = 0; j < col; ++j)
71 {
72 maze[i][j] = getchar();
73 if(maze[i][j] == 'S')
74 {
75 maze[i][j] = 'X'; //起点标记为'X',不能重复走
76 dog_x = i;
77 dog_y = j;
78 }
79 if(maze[i][j] == 'D')
80 {
81 door_x = i;
82 door_y = j;
83 num++;
84 }
85 else
86 if(maze[i][j] == '.')
87 num++; //累加可以走的点
88 }
89 getchar();
90 }
91 //若可行的点 比限制的时间还小,则不能逃出;
92 //或狗 到 门的步数 奇偶性和 限制的步数 奇偶性不同 时 也不能逃出
93 out = false;
94 if( num >= time && (dog_x+dog_y + door_x+door_y) % 2 == time % 2 )
95 dfs(dog_x, dog_y, 0);
96
97 if(out == true)
98 puts("YES");
99 else
100 puts("NO");
101 }
102 return 0;
103 }