ZOJ 2110 Tempter of the Bone

很早就看到这道题了,当时不太会DFS,搜索只会用BFS;

早上看了看书,才发觉DFS是用来解决这种问题的,就把这道题做了,1A;

其中涉及两个剪枝:一个是奇偶性,另一个是可以走的方块的数量要不少于要求的步数。

# include <stdio.h>

# include <math.h>



char maze[10][10], escape;

int n, m, T, sx, sy, dx, dy;



const int dir[][2] = {{-1,0}, {0,-1}, {0,1}, {1,0}};



char read_data(void)

{

    int i;

    

    scanf("%d%d%d", &n, &m, &T);

    if (n==0 && m==0 && T==0) return 0;

    for (i = 1; i <= n; ++i)

    {

        scanf("%s", maze[i]+1);

    }    

    

    return 1;

}



void dfs(int cx, int cy, int d)

{

    int i, nx, ny;

        

    if (T < d) return ;

    

    if (cx==dx && cy==dy && d==T)

    {

        escape = 1;

        return ;

    }

    

    for (i = 0; i < 4; ++i)

    {

        nx = cx + dir[i][0];

        ny = cy + dir[i][1];

        if (1<=nx && nx<=n && 1<=ny && ny<=m && maze[nx][ny]=='.')

        {

            maze[nx][ny] = '*';

            dfs(nx, ny, d+1);

            if (escape == 1) return ;

            maze[nx][ny] = '.';

        }

    }

    

    return ;

}



void solve(void)

{

    int i, j, tmp, wall;

    

    wall = 0;

    for (i = 1; i <= n; ++i)

    for (j = 1; j <= m; ++j)

    {

        if (maze[i][j] == 'S') {sx = i; sy = j;}

        else if (maze[i][j] == 'D') {dx = i; dy = j;maze[i][j] = '.';}   /* 根据搜索的条件,这里目标节点要标记为可行 */

        else if (maze[i][j] == 'X') ++wall;

    }

    

    if (n*m-wall <= T) {puts("NO"); return ;}

    

    tmp = T-abs(sx-dx)-abs(sy-dy);

    if (tmp<0 || tmp%2) puts("NO");

    else

    {

        escape = 0;

        dfs(sx, sy, 0);

        puts(escape==1 ? "YES":"NO");

    }

}



int main()

{
while (read_data()) { solve(); } return 0; }

你可能感兴趣的:(one)