HDU ACM 1010 Tempter of the Bone (深搜+奇偶剪枝)
http://acm.hdu.edu.cn/showproblem.php?pid=1010
题意:有一只狗要从起点S走到终点D
点每走过一次就会下陷,不能再走
且出口只会在时间T时开启
问狗能不能走出迷宫
S 起点
D 终点
X 墙
. 路
思路:一般都会想到用深搜做,要注意的是剪枝
1) 当前步数(rank) > 时间
2) 最短距离小于时间t
3) 奇偶剪枝,x1+x2 + y1+y2 为奇数则必走奇数步数到终点 为偶数则走偶数步数到终点
4) 如果点的数量少于步数
1 #include <iostream> 2 using namespace std; 3 struct Node{ 4 int x; 5 int y; 6 }; 7 Node s,e; 8 int point[4][2] = {0,1,0,-1,1,0,-1,0}; 9 char map[10][10]; 10 int used[10][10]; 11 int t; 12 int n,m; 13 int flag; 14 void DFS(Node now,int rank){ 15 16 if(map[now.x][now.y] == 'D'){ 17 if(rank == t){ 18 flag = 1; 19 return; 20 } 21 22 } 23 if(rank >= t){ 24 return; 25 } 26 27 28 int i; 29 for(i=0;i<4;i++){ 30 int x = now.x + point[i][0]; 31 int y = now.y + point[i][1]; 32 if(x >= 1 && x <= n && y >=1 && y <=m){ 33 if(!used[x][y] && map[x][y] != 'X'){ 34 used[x][y] = 1; 35 Node mid; 36 mid.x = x; 37 mid.y = y; 38 DFS(mid,rank+1); 39 if(flag){ 40 return; 41 } 42 used[x][y] = 0; 43 } 44 } 45 } 46 } 47 int main(){ 48 while(cin>>n>>m>>t,n*m*t){ 49 memset(used,0,sizeof(used)); 50 memset(map,0,sizeof(map)); 51 int num = 0; 52 int i,j; 53 for(i=1;i<=n;i++){ 54 for(j=1;j<=m;j++){ 55 cin>>map[i][j]; 56 if(map[i][j] == 'S'){ 57 s.x = i; 58 s.y = j; 59 used[i][j] = 1; 60 } 61 if(map[i][j] == 'D'){ 62 e.x = i; 63 e.y = j; 64 } 65 if(map[i][j] == 'X'){ 66 num++; 67 } 68 } 69 } 70 if(abs(s.x - e.x)+ abs(s.y - e.y) > t || (s.x+e.x+s.y+e.y+t)%2 == 1 || n*m - num < t+1){ 71 cout<<"NO"<<endl; 72 continue; 73 } 74 flag = 0; 75 DFS(s,0); 76 if(flag){ 77 cout<<"YES"<<endl; 78 } 79 else{ 80 cout<<"NO"<<endl; 81 } 82 } 83 return 0; 84 }