HDU - 1010 (DFS回溯法 + 奇偶剪枝)
Posted dynastysun
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU - 1010 (DFS回溯法 + 奇偶剪枝)相关的知识,希望对你有一定的参考价值。
题目大意:给出一个N*M的迷宫,迷宫中有一扇门D,只有在T时刻会打开,现在你0时刻位于S,你需要在正好在T时刻到达D,你只能上下左右移动,每次移动耗费1时刻,且同一个位置不能进入两次,问是否能在T时刻刚好到达D处。
范围 1 < N,M < 7, 1 < T < 50,这个范围有点大,直接DFS回溯搜会TLE,我们要加上一个剪枝,这个剪枝十分重要,我们求出起点到终点的距离(横向距离 + 纵向距离),若这个距离为奇数,则时间T必须也要为奇数,否则时间T必须为偶数(其中的道理显而易见),只有这样,你才有可能在T时刻到达D。详情见下面的代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #include <queue> 7 #include <stack> 8 using namespace std; 9 10 typedef long long LL; 11 typedef unsigned long long ULL; 12 const int dx[] = {1,-1,0,0}; 13 const int dy[] = {0,0,1,-1}; 14 15 int N, M, T, bx, by, ex, ey; 16 char Map[10][10]; 17 int vis[10][10]; 18 19 bool dfs(int x, int y, int t){ 20 if(x == ex && y == ey && t == T) return true; 21 if(t >= T) return false; 22 for(int i = 0; i < 4; ++i){ 23 int nx = x + dx[i]; 24 int ny = y + dy[i]; 25 if(nx >= 0 && ny >= 0 && nx < N && ny < M){ 26 if(vis[nx][ny]) continue; 27 if(Map[nx][ny] == ‘X‘) continue; 28 vis[nx][ny] = 1; 29 if(dfs(nx, ny, t+1)) return true; 30 vis[nx][ny] = 0; 31 } 32 } 33 return false; 34 } 35 36 int main(){ 37 while(scanf("%d%d%d", &N, &M, &T) == 3 && N){ 38 for(int i = 0; i < N; ++i){ 39 scanf("%s", Map[i]); 40 for(int j = 0; j < M; ++j) 41 if(Map[i][j] == ‘D‘) { 42 ex = i; 43 ey = j; 44 }else if(Map[i][j] == ‘S‘) { 45 bx = i; 46 by = j; 47 } 48 } 49 50 //奇偶剪枝 51 int dis = abs(bx-ex)+abs(by-ey); 52 if(dis%2 != T%2) { 53 printf("NO "); 54 continue; 55 } 56 57 memset(vis, 0, sizeof(vis)); 58 vis[bx][by] = 1; 59 if(dfs(bx, by, 0)) printf("YES "); 60 else printf("NO "); 61 } 62 return 0; 63 }
以上是关于HDU - 1010 (DFS回溯法 + 奇偶剪枝)的主要内容,如果未能解决你的问题,请参考以下文章
hdu1010Tempter of the Bone(dfs+奇偶剪枝)
hdu1010 Tempter of the Bone---DFS+奇偶剪枝