【HDU-1010】Tempter of the Bone

125 阅读2分钟

题目

暑假的时候,小明和朋友去迷宫中寻宝。然而,当他拿到宝贝时,迷宫开始剧烈震动,他感到地面正在下沉,他们意识到这是一个陷阱!他们想尽一切办法逃出去。 迷宫是一个大小为 N*M 的长方形,迷宫中有一扇门。一开始,门是关着的,他会在第 t 秒的时间打开。因为,小明和朋友必须在第 t 秒到大门口。每一秒,他都可以向上下左右四个方向移动一个点。一旦他移动了,他刚才所在的点就消失,(这意味着他不能回到他已经走过的点)。他不能在一个点上停留超过一秒,并且不能走障碍点。小明和朋友能安全的逃出吗?


Input

输入由多个测试用例组成。每个测试用例的第一行包含三个整数 N、M 和 T ( 1 < N , M < 7 ; 0 < T < 50 ),分别表示迷宫的大小和门打开的时间。接下来的N行给出迷宫布局,每一行包含M个字符。下列字母分别表示: “X”: 一堵墙,小明和朋友不能在上面停留 “S”: 起点 “D”: 门 “.”: 可以走的点


Output

对于每组样例输出一行。 如果小明能够安全逃出,输出 “YES” ,否则输出 “NO”。




样例

样例输入
4 4 5
S.X.
..X.
..XD
....
3 4 5
S.X.
..X.
...D
0 0 0



样例输出
NO
YES



AC代码

#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;

int n, m, t, sx, sy, ex, ey, flag;
char map[10][10];
int vis[10][10];
int dir[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

void dfs(int x, int y, int ti)
{
    int dx, dy;
    if (flag == 1 || ti > t)
        return;
    // 在规定时间内正好到达终点
    if (map[x][y] == 'D' && ti == t)
    {
        flag = 1; // 找到了这么一条路
        return;   // 返回
    }

    int tem = t - ti - abs(ex - x) - abs(ey - y); //剪枝的核心代码
    if (tem < 0 || tem & 1)                       //剪枝:如果剩余的步数已经不足以走到出口,且必须是偶数,偶数-偶数=偶数,奇数-奇数=偶数,
        return;
    // 四个方向遍历
    for (int i = 0; i < 4; ++i)
    {
        dx = x + dir[i][0];
        dy = y + dir[i][1];

        // 如果 越界 或 走到墙X 或 已访问过
        if (dx < 0 || dx >= n || dy < 0 || dy >= m || map[dx][dy] == 'X' || vis[dx][dy])
            continue;

        // 新扩展的点标记走过, 对该点进行DFS
        vis[dx][dy] = 1;
        dfs(dx, dy, ti + 1);
        // 回溯后将标记撤回
        vis[dx][dy] = 0;
    }
    return;
}

int main()
{
    while (cin >> n >> m >> t)
    {
        if (n == 0 && m == 0 && t == 0)
            break;
        memset(vis, 0, sizeof(vis));

        for (int i = 0; i < n; ++i)
        {
            cin >> map[i];
        }

        int wall = 0;
        flag = 0;
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < m; j++)
            {
                if (map[i][j] == 'S')
                {
                    sx = i;
                    sy = j;
                }
                if (map[i][j] == 'D')
                {
                    ex = i;
                    ey = j;
                }
                if (map[i][j] == 'X')
                    wall++;
            }
        }

        if (t > n * m - wall - 1)
        {
            cout << "NO" << endl;
            continue;
        }

        vis[sx][sy] = 1;
        dfs(sx, sy, 0);

        if (flag)
            cout << "YES" << endl;
        else
            cout << "NO" << endl;
    }

    return 0;
}



题源:acm.hdu.edu.cn/showproblem…