首页 > 代码库 > HDU 1010 Tempter of the Bone(深度+剪枝)

HDU 1010 Tempter of the Bone(深度+剪枝)

http://acm.hdu.edu.cn/showproblem.php?pid=1010

题意:就是给出了一个迷宫,小狗必须经过指定的步数到达出口,并且每个格子只能走一次。

首先先来介绍一下奇偶性剪枝:

技术分享

在这道题目中,如果使用剪枝的话,可以节省不少的时间。

在这道题目中,每次dfs循环时都可以判断一下小狗当前位置与终点所相差的步数,如果不为偶数的话,说明到达不了终点,就可以退出这个循环,不必继续dfs了。

在这道题目中,由于每个格子只能经过一次,所以经过一次后,可以把该点位置改为‘X’,然后我wa了好久,后来明白每次dfs循环后得把这个点的位置重新改回‘.’。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<string>
 4 using namespace std;
 5 
 6 char map[10][10];
 7 int d[][2] = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } };
 8 int flag,n,m,t,dx,dy;
 9 
10 void dfs(int x,int y,int time)
11 {
12     if (x<1||x>n||y<1||y>m ||flag||time>t)  return;            //出界
13     if (time == t && x==dx && y==dy)
14     {
15         flag = 1;
16         return;
17     }
18     int s1 = x - dx;
19     int s2 = y - dy;
20     int ans = t - time - abs(s1) - abs(s2);       //剪枝,如果当前剩余的所要求的步数减去小狗
21     if (ans<0||ans%2)  return;                    //当前位置与终点的步数不为偶数的话,则结束
22     for (int i = 0; i < 4; i++)
23     {
24         if (map[x + d[i][0]][y + d[i][1]] != X)
25         {
26             map[x + d[i][0]][y + d[i][1]] = X;
27             dfs(x + d[i][0], y + d[i][1], time+1);
28             map[x + d[i][0]][y + d[i][1]] = .;    //这里必须把该点的值还原回来,不然影响后续的dfs
29         }
30     }
31     return;
32 }
33 
34 int main()
35 {
36     int x,y,wall; 
37     while (cin >> n >> m >> t, n && m && t)
38     {
39         if (!m || !n || !t)
40         {
41             cout << "NO" << endl;
42             continue;
43         }
44         flag = 0;
45         wall = 0;
46         for (int i = 1; i <= n;i++)
47         for (int j = 1; j <= m; j++)
48         {
49             cin >> map[i][j];
50             if (map[i][j] == S)
51             {
52                 x = i;
53                 y = j;
54             }
55             if (map[i][j] == D)
56             {
57                 dx = i;
58                 dy = j;
59             }
60             if (map[i][j] == X)
61                 wall++;
62         }
63         if (n*m - wall <t)              //剪枝,如果所有点减去墙小于指定步数,那肯定是不行的
64         {
65             cout << "NO" << endl;
66             continue;
67         }
68         map[x][y] = X;
69         dfs(x,y,0);
70         if (flag == 1)  cout << "YES" << endl;
71         else cout << "NO" << endl;
72     }
73     return 0;
74 }

 

HDU 1010 Tempter of the Bone(深度+剪枝)