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; }

posted on 2012-06-04 10:54  getgoing  阅读(185)  评论(0编辑  收藏  举报

导航