Tempter of the Bone -- BFS 回溯 剪枝

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

此题必须剪枝,不然就不能ac。写过bfs,dfs,都不行,原因是没有剪枝,参考学习下面的代码,不是自己写的 就要敲的变成自己的。

// http://acm.hdu.edu.cn/showproblem.php?pid=1010

//AC代码 可以敲上10遍了
#include <stdio.h>
#include <stdlib.h>
bool flag;
int n, m, t, i, j, x1, y1, x2, y2, num;
int dir[4][2] = { { 0, -1 }, { 0, 1 }, { 1, 0 }, { -1, 0 } };  //设置四个方向,分别是左、右、下、上
char str[8][8];

int vis[8][8];

void BFS(int k, int l, int tc)
{
    int i;
    if (tc == t && k == x2 &&l == y2)
        flag = true;
    if (flag) 
        return;
    // 这里是当前点到终点的距离 和 当前点到终点的距离 
    if ((abs(x2 - k) + abs(y2 - l)) % 2 != (t - tc) % 2)  // 路径长度 和 t(所要求的时间)要一致 都为偶数或者都为奇数
        return;   //奇偶性剪枝的判断条件

    for (i = 0; i < 4; i++)
    {
        int dx = k + dir[i][0];
        int dy = l + dir[i][1];
        // 可以走 并且在范围内
        if (dx >= 0 && dx < n && dy >= 0 && dy < m && str[dx][dy] != 'X' && !vis[dx][dy])
        {
            //str[dx][dy] = 'X';
            vis[dx][dy] = true;
            BFS(dx, dy, tc + 1);
            //str[dx][dy] = '.'; //此方向如果不行的话就回溯
            vis[dx][dy] = false;
        }
    }
}
int main()
{
    //freopen("in", "r", stdin);
    while (scanf("%d%d%d", &n, &m, &t))
    {
        if (n == 0 && m == 0 && t == 0)
            break;
        getchar();// 
        num = 0;
        for (i = 0; i < n; i++)
        {
            for (j = 0; j < m; j++)
            {
                vis[i][j] = false;
                scanf("%c", &str[i][j]);
                if (str[i][j] == 'S')
                {
                    x1 = i; y1 = j;
                }
                else if (str[i][j] == 'D')
                {
                    x2 = i; y2 = j;
                    num++;
                }
                else if (str[i][j] == '.')
                {
                    num++;
                }
            }
            getchar();//
        }
        flag = false; // flag 置为 false
        str[x1][y1] = 'X';
        if (num >= t){ // 只有num 大于等于 t 才可能恰好等于t时刻到达
            BFS(x1, y1, 0); // 第 0 步开始
            vis[x1][y1] = true;
        }
        if (flag)
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}

你可能感兴趣的:(bfs,剪枝)