很早就看到这道题了,当时不太会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; }