hdu 1010 Tempter of the Bone
题目连接
http://acm.hdu.edu.cn/showproblem.php?pid=1010
Tempter of the Bone
Description
The doggie found a bone in an ancient maze, which fascinated him a lot. However, when he picked it up, the maze began to shake, and the doggie could feel the ground sinking. He realized that the bone was a trap, and he tried desperately to get out of this maze.
The maze was a rectangle with sizes N by M. There was a door in the maze. At the beginning, the door was closed and it would open at the T-th second for a short period of time (less than 1 second). Therefore the doggie had to arrive at the door on exactly the T-th second. In every second, he could move one block to one of the upper, lower, left and right neighboring blocks. Once he entered a block, the ground of this block would start to sink and disappear in the next second. He could not stay at one block for more than one second, nor could he move into a visited block. Can the poor doggie survive? Please help him.
Input
The input consists of multiple test cases. The first line of each test case contains three integers N, M, and T (1 < N, M < 7; 0 < T < 50), which denote the sizes of the maze and the time at which the door will open, respectively. The next N lines give the maze layout, with each line containing M characters. A character is one of the following:
'X': a block of wall, which the doggie cannot enter;
'S': the start point of the doggie;
'D': the Door; or
'.': an empty block.
The input is terminated with three 0's. This test case is not to be processed.
Output
For each test case, print in one line "YES" if the doggie can survive, or "NO" otherwise.
Sample Input
4 4 5
S.X.
..X.
..XD
....
3 4 5
S.X.
..X.
...D
0 0 0
Sample Output
NO
YES
一开始用bfs写的wa掉了,点开discus然后用dfs写tle %>_<%。。查了下资料发现有奇偶剪枝这东西,敲上ok。。
奇偶剪枝参见度娘。。
http://baike.baidu.com/history/%E5%A5%87%E5%81%B6%E5%89%AA%E6%9E%9D/76619083
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<vector> 7 #include<queue> 8 #include<map> 9 using std::abs; 10 using std::cin; 11 using std::cout; 12 using std::endl; 13 using std::find; 14 using std::sort; 15 using std::map; 16 using std::pair; 17 using std::queue; 18 using std::vector; 19 using std::multimap; 20 #define pb(e) push_back(e) 21 #define sz(c) (int)(c).size() 22 #define mp(a, b) make_pair(a, b) 23 #define all(c) (c).begin(), (c).end() 24 #define iter(c) decltype((c).begin()) 25 #define cls(arr,val) memset(arr,val,sizeof(arr)) 26 #define cpresent(c, e) (find(all(c), (e)) != (c).end()) 27 #define rep(i, n) for (int i = 0; i < (int)(n); i++) 28 #define tr(c, i) for (iter(c) i = (c).begin(); i != (c).end(); ++i) 29 const int N = 10; 30 typedef unsigned long long ull; 31 bool vis[N][N]; 32 char G[N][N]; 33 int H, W, T, Sx, Sy, Dx, Dy; 34 const int dx[] = { 0, 0, -1, 1 }, dy[] = { -1, 1, 0, 0 }; 35 bool dfs(int x, int y, int s) { 36 // 找到一个解就直接返回 37 if (s == T && x == Dx && y == Dy) return true; 38 int tmp = abs(x - Dx) + abs(y - Dy) - abs(T - s); 39 // 当前位置到终点的所需要的时间大于剩下的时间 40 // 奇偶性剪枝 ,起点和终点确定以后就可以确定走的步数是奇数还是偶数(没这个会超时滴%>_<%) 41 if (tmp > 0 || tmp & 1) return false; 42 rep(i, 4) { 43 int nx = x + dx[i], ny = y + dy[i]; 44 if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue; 45 if (vis[nx][ny] || G[nx][ny] == 'X') continue; 46 vis[nx][ny] = true; 47 if (dfs(nx, ny, s + 1)) return true; 48 vis[nx][ny] = false; 49 } 50 return false; 51 } 52 int main() { 53 #ifdef LOCAL 54 freopen("in.txt", "r", stdin); 55 freopen("out.txt", "w+", stdout); 56 #endif 57 while (~scanf("%d %d %d", &H, &W, &T) && H + W + T) { 58 int tot = 0; 59 rep(i, H) { 60 scanf("%s", G[i]); 61 rep(j, W) { 62 vis[i][j] = false; 63 if (G[i][j] == 'S') Sx = i, Sy = j; 64 if (G[i][j] == 'D') Dx = i, Dy = j; 65 if (G[i][j] == 'X') tot++; 66 } 67 } 68 // 能走的格子个数比时间少的话,直接不符合,不用再搜了 69 if (H * W - tot <= T) { puts("NO"); continue; } 70 vis[Sx][Sy] = true; 71 puts(dfs(Sx, Sy, 0) ? "YES" : "NO"); 72 } 73 return 0; 74 }