HDU 1010 Tempter of the Bone(深度+剪枝)
Posted 谦谦君子,陌上其华
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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(深度+剪枝)的主要内容,如果未能解决你的问题,请参考以下文章
题解报告:hdu 1010 Tempter of the Bone
HDU 1010 Tempter of the Bone(dfs)