题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1010
转自:http://www.cnblogs.com/zhourongqing/archive/2012/04/28/2475684.html
深度优先搜索,用到了奇偶剪枝,第一次听说。。仍然是咸鱼一条
奇偶剪枝:
是数据结构的搜索中,剪枝的一种特殊小技巧。
现假设起点为(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 <map> 3 #include <set> 4 #include <cmath> 5 #include <queue> 6 #include <stack> 7 #include <cstdio> 8 #include <string> 9 #include <vector> 10 #include <cstring> 11 #include <iostream> 12 #include <algorithm> 13 #include <functional> 14 #include<string.h> 15 using namespace std; 16 #define rep(i,a,n) for (int i=a;i<=n;i++) 17 #define per(i,a,n) for (int i=n;i>=a;i--) 18 #define pb push_back 19 #define mp make_pair 20 #define all(x) (x).begin(),(x).end() 21 #define fi first 22 #define se second 23 #define SZ(x) ((int)(x).size()) 24 typedef vector<int> VI; 25 typedef long long ll; 26 typedef pair<int, int> PII; 27 const ll mod = 1000000007; 28 // head 29 const int MAX_N = 10; 30 31 int i_add[] = { 0,1,0,-1 }; 32 int j_add[] = { 1,0,-1,0 }; 33 34 int n, m, t; 35 int stai, staj, endi, endj; 36 char maze[MAX_N][MAX_N]; 37 bool visited[MAX_N][MAX_N]; 38 bool res = false; 39 40 bool dfs(int i, int j, int d) { 41 if (res) return true; 42 if (i < 0 || j < 0 || i >= n || j >= m) return false; 43 if (d > t) return false; 44 if (maze[i][j] == ‘D‘&&d == t) return res = true; 45 int tmp = t - d - abs(i - endi) - abs(j - endj); 46 if (tmp & 1) return false; 47 48 int ii, jj; 49 ii = i - 1, jj = j; 50 if (!visited[ii][jj] && maze[ii][jj] != ‘X‘) { 51 visited[ii][jj] = true; 52 dfs(ii, jj, d + 1); 53 visited[ii][jj] = false; 54 } 55 ii = i, jj = j - 1; 56 if (!visited[ii][jj] && maze[ii][jj] != ‘X‘) { 57 visited[ii][jj] = true; 58 dfs(ii, jj, d + 1); 59 visited[ii][jj] = false; 60 } 61 ii = i + 1, jj = j; 62 if (!visited[ii][jj] && maze[ii][jj] != ‘X‘) { 63 visited[ii][jj] = true; 64 dfs(ii, jj, d + 1); 65 visited[ii][jj] = false; 66 } 67 ii = i, jj = j + 1; 68 if (!visited[ii][jj] && maze[ii][jj] != ‘X‘) { 69 visited[ii][jj] = true; 70 dfs(ii, jj, d + 1); 71 visited[ii][jj] = false; 72 } 73 return false; 74 } 75 76 int main(){ 77 while (scanf("%d %d %d", &n, &m, &t)) { 78 if (n == 0 && m == 0 && t == 0) { 79 break; 80 } 81 memset(maze, 0, sizeof(maze)); 82 //initialize 83 memset(visited, 0, sizeof(visited)); 84 int k = 0; 85 86 for (int i = 0; i < n; i++) { 87 for (int j = 0; j < m; j++) { 88 scanf(" %c", &maze[i][j]); 89 if (maze[i][j] == ‘S‘) { 90 stai = i, staj = j; 91 } 92 if (maze[i][j] == ‘D‘) { 93 endi = i, endj = j; 94 } 95 if (maze[i][j] == ‘X‘) k++; 96 } 97 } 98 if (n*m - k - 1 < t) 99 { 100 cout << "NO" << endl; 101 } 102 else { 103 dfs(stai, staj, 0); 104 if (res) 105 cout << "YES" << endl; 106 else 107 cout << "NO" << endl; 108 } 109 } 110 return 0; 111 }
时间: 2024-10-14 14:14:14