存在的问题:1、对深搜和广搜的理解不深刻,特别是回溯的状态与条件。2、实现一个算法的速度还比较慢! 3、以后少花时间去追程序的BUG,多花时间去想想算法!
奇偶剪枝的原理:
2 #include<stdlib.h>
3 #include<string.h>
4 #define MAX_LEN 1
5
6 char maze[MAX_LEN + 10][MAX_LEN + 10];
7 const int move[4][2]={{0, 1},{1, 0},{0, -1},{-1, 0}};
8 int flag[MAX_LEN + 10][MAX_LEN + 10];
9
10 int n , m;
11 int N , M , T;
12 int r , c;
13 int escape;
14 int empty;
15
16
17 bool Check(int x , int y)
18 {
19 if(!flag[x][y] && maze[x][y] != 'X' && x >= 0 && x < N && y >= 0&& y < M )
20 return 1;
21 return 0;
22 }
23
24
25
26 void dfs(int x , int y, int t)
27 {
28 if(escape) return ; //flag[x][y] = 1的话使得原来的点只能走一次,而不能回溯了!
29 int tmp = T - t - abs(x - n) - abs(y - m);
30 if(tmp < 0 || tmp & 1) return ;
31 if(x == n && y == m && t == T) { escape = 1; return ; }
32 for(int i = 0; i < 4; i++)
33 {
34 int xx = x + move[i][0];
35 int yy = y + move[i][1];
36 if(Check(xx , yy))
37 {
38 flag[xx][yy] = 1; //标记的记录
39 dfs(xx , yy , t+1);
40 flag[xx][yy] = 0; //回溯
41 }
42 }
43 return ;
44 }
45
46
47
48 int main()
49 {
50 while(~scanf("%d%d%d",&N , &M , &T ) , N , M , T)
51 {
52 int i,j;
53
54 escape = empty = 0;
55
56 for(i = 0;i < N; i++) //当时是用scanf("%c",&maze[i][j]),相当麻烦!~
57 {
58 scanf("%s", maze[i]);
59 getchar();
60 for(j = 0;j < M; j++)
61 {
62 if(maze[i][j] == 'S') {r = i; c = j;}
63 if(maze[i][j] == 'D') { n = i; m = j; }
64 if(maze[i][j] == '.') { empty ++;} //步数剪枝
65 }
66 }
67
68
69 memset(flag , 0 , sizeof(flag));
70
71 if(T > empty+1) { printf("NO\n"); continue; }
72 flag[r][c] = 1; //起点标记
73 dfs ( r , c , 0);
74
75 if(escape) printf("YES\n");
76 else printf("NO\n");
77 }
78 return 0;
79 }