搜索DFS

杭电1010 Tempter of the Bone  原题连接http://acm.hdu.edu.cn/showproblem.php?pid=1010
代码如下:
#include <iostream> using namespace std; char map[8][8]; int r, c, ttime, x2, y2; //ttime 是所给时间T,【r:行、c:列】 bool flag; //x2、y2是终点坐标 int x_move[4] = {0, 1, -1, 0}; int y_move[4] = {1, 0, 0, -1}; void dfs (int x, int y, int t) //t是走到当前坐标时的时刻 { if (t > ttime) //超时 return ; // 下面的tmp的意义:【剩余时间(ttime - t)(记为left)】与【从当前坐标走到终点所需时间( abs(x-x2) + abs(y- y2) )(记为win)】的差,如果tmp是奇数,说明left与win的奇偶性不同!也就是说在第T秒时,不可能从当前坐标走到终点! int tmp = ttime - t - abs(x-x2) - abs(y-y2); if (tmp < 0 || tmp & 1) //奇偶剪枝,非常重要,很抽象 Orz... return ; for (int i = 0; i < 4; i++) { int tx = x + x_move[i]; int ty = y + y_move[i]; if (tx < 0 || ty < 0 || tx >= r || ty >= c) continue; if (map[tx][ty] == 'D' && t + 1 == ttime)//到达终点且该时刻t+1为所给时间,即成功到达 { flag = true; return ; } if (map[tx][ty] == '.') { map[tx][ty] = 'X'; //已走格子变成墙,根据题意,已走格子不可再走 dfs (tx, ty, t+1); if (flag) //成功 return ; map[tx][ty] = '.'; //回溯 } } } int main() { int i, j, x1, y1, empty; while (scanf ("%d%d%d", &r, &c, &ttime) != EOF) { if (!r && !c && !ttime) break; empty = 0; for (i = 0; i < r; i++) { scanf ("%s", map[i]); for (j = 0; j < c; j++) { if (map[i][j] == 'S') //找到起点的坐标 x1 = i, y1 = j; if (map[i][j] == 'D') //找到终点的坐标 x2 = i, y2 = j; if (map[i][j] == '.') //计算总的可能行走的步数 empty++; } } if (empty + 1 < ttime) //步数剪枝,常识,可行步数小于总时间,在T时刻肯定不可走到终点 { puts ("NO"); continue; } flag = false; dfs (x1, y1, 0); if (flag) puts ("YES"); else puts ("NO"); } return 0; }

 

 

posted @ 2013-03-11 11:50  supersnow0622  Views(123)  Comments(0)    收藏  举报