1 /**
2 通过一个题目来认识深度优先搜索
3 题目描述:
4 一个N*M迷宫,入口S,出口D,能走的是.,不能走的是X,问从入口进入后能否在T时间内走出迷宫?
5
6 输入:
7 N,M,T分别代表迷宫的长度和宽度以及时间,注意三者输入都是0时,结束
8
9 输出:
10 能走出为YES;不能走出为NO
11
12 样例输入:
13 4 4 5
14 S.X.
15 ..X.
16 ..XD
17 ....
18 3 4 5
19 S.X.
20 ..X.
21 ...D
22 0 0 0
23
24 样例输出:
25 NO
26 YES
27 代码用VS2012有点儿小问题哈~*/
28
29 #include<cstdio>
30 #include<cstdlib>
31 using namespace std;
32
33 char maze[101][101];//保存地图信息
34 int n, m ,t;//地图大小为n * m,从起点到终点能否恰为t秒
35 bool success;//是否找到所需状态标记
36 int go[][2] = {1, 0, -1, 0, 0, 1, 0, -1};//四方向行走坐标差
37
38 //递归形式的深度优先搜索
39 void DFS(int x, int y, int time)
40 {
41 //枚举四个相邻位置
42 for(int i = 0 ; i < 4 ; i ++)
43 {
44 //nx表示上下坐标,ny表示左右坐标,其实是一样的~~
45 int nx = x + go[i][0];
46 int ny = y + go[i][1];//计算其坐标
47
48 if(nx < 1 || nx > n || ny < 1 || ny > m)//超出界限
49 continue;
50
51 if(maze[nx][ny] == 'X')//路障
52 continue ;
53 if(maze[nx][ny] == 'D')//出口
54 {
55 if(time + 1 == t)//再走一步,时间恰好为t,皆大欢喜
56 {
57 success = true;
58 return ;
59 }
60 else
61 continue;
62 }
63 maze[nx][ny] = 'X';//将走过的格子设为路障
64
65 DFS(nx, ny, time +1);//递归进行下一次搜索
66 maze[nx][ny] = '.';//若其后状态全部搜索完毕,则退回上层状态,将因为搜索其后续状态改成路障的位置改为普通位置
67
68 if(success)
69 return ;
70 }
71 }
72
73 int main()
74 {
75 while(scanf_s("%d%d%d", &n, &m, &t) != EOF)
76 {
77 if( n ==0 && m == 0 && t ==0)
78 break;
79 getchar();
80 for(int i = 1 ; i <= n ; i ++)
81 {
82 gets_s(maze[i] + 1, m);
83 }//输入
84
85 success = false;//初始化成功标记
86
87 //找到出口
88 int sx, sy;
89 for(int i = 1 ; i <= n ; i ++)
90 {
91 for(int j = 1 ; j <= m ; j ++)
92 {
93 if(maze[i][j] == 'D')
94 {
95 sx = i;
96 sy = j;
97 }
98 }
99 }
100 for(int i = 1 ; i <= n ; i ++)
101 {
102 for(int j = 1 ; j <= m ; j ++)
103 {
104 //找到S点后,先判断S与D的就关系,是否符合t,不符合的话直接跳过搜索
105 if(maze[i][j] == 'S' && (i + j) % 2 == ((sx + sy) % 2 + t % 2) % 2 )
106 {
107 maze[i][j] = 'X';
108 DFS(i, j, 0);
109 }
110 }
111 }
112
113 puts(success == true ? "YES" : "NO");//输出结果
114 }
115
116 return 0;
117 }