hdu1010 经典的DFS+奇偶剪枝

来源:互联网 发布:荣耀盒子 软件 编辑:程序博客网 时间:2024/06/08 10:56

这题很久以前做的,不过当时没AC - -后来发现是count没有放在代码里面(注意有多组测试数据 - -)

DFS注意回溯的话要把访问标记重置。

剪枝代码放在DFS两个地方,一个是访问领接点之前,这是对一个点状态剪枝,另外一个是放在访问领接点的代码里,是对多个状态的比较关系剪枝。

奇偶剪枝:剩余步数和最小步数的奇偶性相同

#include<iostream>using namespace std;#define start 1#define end 0int map[100][100];bool DFS(int x, int y, int ex, int ey, int m, int n, int t, int step)//带上状态 当前步数{int min = abs(x - ex) + abs(y - ey);if (x>=m || y>=n|| x <0 || y <0)//出界  return false;if (x == ex&&y == ey&&step == t){    return true;}   //终点情况if ((t - step) < min || (t - step - min) % 2 != 0)return false;if (step >= t) return false;if (!map[x + 1][y]){map[x + 1][y] = 1; if (DFS(x + 1, y, ex, ey, m, n, t, step + 1)){ return true; } map[x + 1][y] = 0;}if (!map[x - 1][y]){map[x - 1][y] = 1; if (DFS(x - 1, y, ex, ey, m, n, t, step + 1)) { return true; }map[x - 1][y] = 0;}if (!map[x][y + 1]){map[x][y + 1] = 1;if (DFS(x, y + 1, ex, ey, m, n, t, step + 1)){ return true; } map[x][y + 1] = 0;}if (!map[x][y - 1]){map[x][y - 1] = 1; if (DFS(x, y - 1, ex, ey, m, n, t, step + 1)) { return true; } map[x][y - 1] = 0;}return false;}int main(){int m, n, ex, ey, t, count , sx, sy;char ch;while (cin >> m >> n >> t, n + m + t){count = 0;for (int i = 0; i < m; i++)for (int j = 0; j < n; j++){cin >> ch;if (ch == 'S')map[i][j] = start, sx = i, sy = j;if (ch == 'D')map[i][j] = end, ex = i, ey = j;if (ch == '.')map[i][j] = 0;if (ch == 'X')map[i][j] = 1, count++;}if (n*m - count <=t){cout << "NO"<<endl; continue;//可行性剪枝}if (DFS(sx, sy, ex, ey, m, n, t, 0))cout << "YES" << endl;elsecout << "NO" << endl;}}


0 0
原创粉丝点击