hdu1010:Tempter of the Bone 搜索+剪枝

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1010

转自:http://www.cnblogs.com/zhourongqing/archive/2012/04/28/2475684.html

2017 5 15

  果然之前理解不到位,dfs回溯还是有套路的啊,更新一下代码。

深度优先搜索,用到了奇偶剪枝,第一次听说。。仍然是咸鱼一条

 

奇偶剪枝:
是数据结构的搜索中,剪枝的一种特殊小技巧。
现假设起点为(sx,sy),终点为(ex,ey),给定t步恰好走到终点,
 
s        
|        
|        
|        
+ e
 
如图所示(“|”竖走,“—”横走,“+”转弯),易证abs(ex-sx)+abs(ey-sy)为此问题类中任意情况下,起点到终点的最短步数,记做step,此处step1=8;
  
s  
  +  
| +      
|        
+ e
 
如图,为一般情况下非最短路径的任意走法举例,step2=14;
step2-step1=6,偏移路径为6,偶数(易证);
故,若t-[abs(ex-sx)+abs(ey-sy)]结果为非偶数(奇数),则无法在t步恰好到达;
返回,false;
反之亦反。
 
刚开始也是写了宽搜,结果wa,看题,提取关键字!
代码:
 1 #define _CRT_SECURE_NO_WARNINGS
 2 #include <functional>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <cstring>
 6 #include <cassert>
 7 #include <cstdio>
 8 #include <cctype>
 9 #include <vector>
10 #include <string>
11 #include <queue>
12 #include <stack>
13 #include <cmath>
14 #include <map>
15 #include <set>
16 using namespace std;
17 #define rep(i,a,n) for (int i=a;i<n;i++)
18 #define per(i,a,n) for (int i=n-1;i>=a;i--)
19 #define pb push_back
20 #define mp make_pair
21 #define all(x) (x).begin(),(x).end()
22 #define fi first
23 #define se second
24 #define SZ(x) ((int)(x).size())
25 typedef vector<int> VI;
26 typedef long long ll;
27 typedef pair<int, int> PII;
28 const ll mod = 1000000007;
29 ll powmod(ll a, ll b) { ll res = 1; a %= mod; assert(b >= 0); for (; b; b >>= 1) { if (b & 1)res = res*a%mod; a = a*a%mod; }return res; }
30 // head
31 const int inf = 0x3f3f3f3f;
32 #define maxn 10
33 const int iadd[] = {0, 1, 0, -1}, jadd[] = {1, 0, -1, 0};
34 char maze[maxn][maxn];
35 int T, sposi, sposj, dposi, dposj, n, m;
36 int vis[maxn][maxn], step = 0;
37 bool flag = false;
38 
39 int dfs(int si, int sj){
40     if(si == dposi && sj == dposj){
41         if(step == T) 
42             flag = true;
43         return 0;
44     }
45     
46     int tmp1 = abs(dposi - si) + abs(dposj - sj);
47     int tmp2 = abs(T - step);
48     tmp1 &= 1; tmp2 &= 1;
49     if(tmp1 != tmp2){
50         return 0;
51     }
52     
53     for(int i = 0; i < 4; i++){
54         int nexti = si + iadd[i];
55         int nextj = sj + jadd[i];
56         if(nexti < 0 || nexti >= n || nextj < 0 || nextj >= m)
57             continue;
58         if(vis[nexti][nextj] || maze[nexti][nextj] == 'X')
59             continue;
60         step++;
61         vis[nexti][nextj] = 1;
62         dfs(nexti, nextj);
63         step--;
64         vis[nexti][nextj] = 0;
65         if(flag) 
66             break;
67     }
68     return 0;
69 }
70 
71 int main(){
72     while(scanf("%d %d %d", &n, &m, &T) && n){
73         memset(vis, 0, sizeof(vis));
74         memset(maze, 0, sizeof(maze));
75         step = 0; flag = false;
76         for(int i = 0; i < n; i++){
77             for(int j = 0; j < m; j++){
78                 scanf(" %c", &maze[i][j]);
79                 if(maze[i][j] == 'S'){
80                     sposi = i, sposj = j;
81                 }
82                 if(maze[i][j] == 'D'){
83                     dposi = i, dposj = j;
84                 }
85             }
86         }
87         vis[sposi][sposj] = 1;
88         dfs(sposi, sposj);
89         if(flag){
90             printf("YES\n");
91         }
92         else{
93             printf("NO\n");
94         }
95     }
96 }

 

posted @ 2017-04-07 20:00  EricJeffrey  阅读(186)  评论(1编辑  收藏  举报