题意:从S出发到D停止,并且要在指定的时间t走到(不早不晚)。注意,每个‘.’只能走一次。
分析:DFS,但是用普通的dfs,TL, 所以要剪枝。我们可以想到,如果可以早到D点,但是D点周围有其他可以踩的点,并且可以观察到,从一个点(不是D点)到D点的距离(abs(x-dx)+abs(y-dy))是奇数的话,就要走奇数步,偶数的就走偶数步,()
代码:
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <iostream> using namespace std; #define M 10 const int dx[4] = {0, 0, -1, 1}; const int dy[4] = {1, -1, 0, 0}; char map[M][M]; int n, m, t; int sx, sy, ex, ey; int limit(int x, int y) { return (map[x][y] != 'X'&&x>=0&&x<n&&y>=0&&y<m); } int dfs(int x, int y, int step) { if(x == ex&&y == ey&&step == t) return 1; int nx, ny; int temp = t-step-abs(x-ex)-abs(y-ey);//t-step是剩下的要走的,abs(。。)是距离D 点的距离,相减肯定是偶数, if(temp < 0||temp&1) return 0; int i; for(i = 0; i < 4; i ++){ nx = x+dx[i]; ny = y+dy[i]; if(limit(nx, ny)){ map[nx][ny] = 'X'; if(dfs(nx, ny, step+1)) return 1; map[nx][ny] = '.'; } } return 0; } int main() { int i, j; while(scanf("%d%d%d", &n, &m, &t), n||m||t){ memset(map, 0, sizeof(map)); for(i = 0; i < n; i++){ scanf("%s", map[i]); } for(i = 0; i < n; i ++){ for(j = 0; j < m; j ++){ if(map[i][j] == 'S'){ sx = i; sy = j; } if(map[i][j] == 'D'){ ex = i; ey = j; } } } map[sx][sy] = 'X'; //这里一定要注意,要初始化 int ans = dfs(sx, sy, 0); printf("%s\n", ans?"YES":"NO"); } return 0; }
hdoj 1010 Tempter of the Bone 【DFS】+【奇偶剪枝】
原文地址:http://blog.csdn.net/shengweisong/article/details/38758765