zoukankan      html  css  js  c++  java
  • 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 }
    View Code
    By: GadyPu 博客地址:http://www.cnblogs.com/GadyPu/ 转载请说明
  • 相关阅读:
    Android应用程序与SurfaceFlinger服务的关系概述和学习计划【转】
    Linux内核的LED设备驱动框架【转】
    电源管理-4种休眠方式状态
    linux 管道,输出重定向,后端执行
    find 和grep的区别
    linux启动脚本
    linux启动介绍
    sudo的使用
    ps aux|grep *** 解释
    php图片防盗链
  • 原文地址:https://www.cnblogs.com/GadyPu/p/4629888.html
Copyright © 2011-2022 走看看