HDU 1010题解这是一道简单的DFS加回溯题,看懂后就会对递归和回溯有较深刻的理解。
1 #include<iostream>
2 #include<cstdio>
3
4 using namespace std;
5
6 char s[7][7]; //将变量名放在主函数外面为了递归调用时方便。
7 int n,m,t,ok;
8 int visit[7][7];
9 int dir[4][2] = {-1,0,0,1,1,0,0,-1};//分为查找的四个方向
10 int Si,Sj,di,dj;
11
12 int dfs(int x,int y,int step)
13 {
14 if(ok == 1) return 0; //ok==1表示找到出口了
15 if(step == t)
16 {
17 if(x==di&&y==dj)
18 ok = 1;
19 return 0;
20 }
21 if(abs(di-x)+abs(dj-y) > t-step)//重要剪枝,直接到目的地的距离都大于身下的步数,他就不可能到达,好好体会!
22 return 0;
23 if((abs(di-x)+abs(dj-y))%2 != (t-step)%2)
24 return 0;
25
26 for(int i=0; i<4; i++)
27 {
28 int x1 =x + dir[i][0];
29 int y1 =y + dir[i][1];
30 if(x1>=1&&x1<=n&&y1>=1&&y1<=m&&visit[x1][y1]==0&&s[x1][y1]!='X')
31 {
32 visit[x1][y1] = 1;
33 dfs(x1,y1,step+1);
34 visit[x1][y1] = 0;//回溯时要饭标记这是DFS递归的重要技巧
35 }
36 }
37 }
38
39 int main()
40 {
41 while(cin>>n>>m>>t)
42 {
43 if(n==0&&m==0&&t==0)
44 break;
45 int wall = 0;
46 for(int i=1; i<=n; i++)
47 for(int j=1; j<=m; j++)
48 {
49 cin>>s[i][j];
50 if(s[i][j]=='S')
51 {
52 Si = i;
53 Sj = j;
54 }
55 if(s[i][j]=='D')
56 {
57 di = i;
58 dj = j;
59 }
60 if(s[i][j]=='X')
61 {
62 wall++;
63 }
64 visit[i][j] = 0;
65 }
66 if(n*m-wall-1<t)
67 {
68 printf("NO\n");
69 continue;
70 }
71 ok = 0;
72 visit[Si][Sj] = 1;
73 dfs(Si,Sj,0);
74 if(ok==1)
75 printf("YES\n");
76 else
77 printf("NO\n");
78 }
79 return 0;
80 }
81
82