Sample Input:
4 4 5Sample Output:
NOYES
详细代码及解析如下:
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <map> #include <set> #include <algorithm> #define MAXN 100 #define RST(N)memset(N, 0, sizeof(N)) using namespace std; char Map[MAXN][MAXN]; //地图 int N, M, T; //地图size,逃脱时间 bool escape = false; //能否逃脱 int Sx, Sy, Ex, Ey, wall; //起始坐标,目标坐标,墙壁数目 const int dx[] = {0, 0, 1, -1}; //方向数组 const int dy[] = {-1, 1, 0, 0}; bool check(int x, int y) //判断是否能往下一个格子前进 { return x>=0 && y>=0 && x<N && y<M && Map[x][y]!='X'; } void DFS(int px, int py, int cnt) { if(px==Ex && py==Ey && cnt==T) { //顺利逃脱 escape = true; return ; } //abs(x-ex)+abs(y-ey)表示现在所在的格子到目标格子的距离(不能走对角线) //T-cnt是实际还需要的步数,将它们做差 //如果tmp<0或tmp为奇数,那就不可到达! int tmp = (T-cnt) - fabs(px-Ex) - fabs(py-Ey); //搜索过程中的奇偶剪枝 if(tmp < 0 || tmp % 2) return ; for(int i=0; i<4; i++) { int xx = px + dx[i]; int yy = py + dy[i]; if(check(xx, yy)) { Map[xx][yy] = 'X'; //将当前方格设置为墙壁 DFS(xx, yy, cnt+1); //深度遍历 if(escape) return ; Map[xx][yy] = '.'; //状态恢复,回溯 } } return ; } int main(int argc, char *argv[]) { while(~scanf("%d %d %d", &N, &M, &T) && N || M || T) { wall = 0; for(int i=0; i<N; i++) { //地图输入 scanf("%s", Map[i]); for(int j=0; Map[i][j]; j++) { if(Map[i][j] == 'S') { Sx=i, Sy=j; } else if(Map[i][j] == 'D') { Ex=i, Ey=j; } else if(Map[i][j] == 'X') wall++; //统计墙的块数 } } if(N*M-wall <= T) { //搜索前的剪枝 puts("NO"); continue; } escape = false; //初始化为false Map[Sx][Sy] = 'X'; //走过的块变成墙,保证一次走过 DFS(Sx, Sy, 0); if(escape) puts("YES"); else puts("NO"); } return 0; }
HDU 1010 && ZOJ 2110 Tempter of the bone (DFS + 奇偶剪枝)
原文地址:http://blog.csdn.net/keshacookie/article/details/44021213