的问题是,在测试修剪。
应该说是更先进的应用。
由于使用的heuristic(经验)修剪。总结这方面的经验法则,别easy。我说,这也是由于先进的在线报告中的应用程序没有分析太多太好的解决这个问题,计划给也很慢,只有失去了。从这个很多人不这样做的问题。
这里我须要更正一下网上流行的说法:奇偶剪枝法。
事实上本题使用奇偶剪枝法并不能太大提快速度,只能说只让使用奇偶剪枝过掉。
所以网上说本题使用奇偶剪枝的,事实上并不能提快速度。
原因:
奇偶剪枝仅仅能剪枝一次,不能在递归的时候剪枝,由于仅仅要初始化位置符合奇偶性,那么之后的随意方格都会符合奇偶性。
故此理论上也是不能提快速度的。当然本人也实验过多次。证实奇偶剪枝至少对本题来说用处不大。
本题的主要剪枝法应该是一条: 最大空格数和步数比較。就是说假设生下的空格数位grids。而须要走T步,grids < T的时候,就能够判定为NO了。
当然还有第二条剪枝:假设当前位置到目标位置最少须要steps步。而须要走T步,那么steps > T,就能够判定为NO了。
只是事实证明仅仅须要使用第一个剪枝法就能够了。
第二条剪枝用处也不大,原因:递归的格子非常少。计算距离差并不能提高多少速度。
如我以下递归循环中仅仅使用一条主要剪枝就足够了,不超100ms。尽管没有做到0ms,只是速度已经是够快的了。
0ms预计须要进一步的剪枝。有大牛,请不吝赐教一下。有空要深入研究一下A*算法才行了。
int sr = 0, sc = 0, dr = 0, dc = 0, n, m, grids, Tsec; vector<string> maze; bool escapeMaze() { if (sr == dr && sc == dc) { if (Tsec == 0) return true; return false; } if (grids < Tsec) return false; if (Tsec == 0) return false; maze[sr][sc] = '$'; grids--; Tsec--; if (sr+1 <(int)maze.size() && maze[sr+1][sc] == '.') { sr++; if (escapeMaze()) return true; sr--; } if (sc+1 < (int)maze[0].size() && maze[sr][sc+1] == '.') { sc++; if (escapeMaze()) return true; sc--; } if (sc > 0 && maze[sr][sc-1] == '.') { sc--; if (escapeMaze()) return true; sc++; } if (sr > 0 && maze[sr-1][sc] == '.') { sr--; if (escapeMaze()) return true; sr++; } maze[sr][sc] = '.'; grids++; Tsec++; return false; } int main() { while (scanf("%d %d %d", &n, &m, &Tsec) && n) { grids = n * m - 1; maze.clear(); maze.resize(n); for (int i = 0; i < n; i++) { cin>>maze[i]; for (int j = 0; j < m; j++) { if (maze[i][j] == 'S') sr = i, sc = j; //别忘记了这里是'S' else if (maze[i][j] == 'D') dr = i, dc = j, maze[i][j] = '.'; else if (maze[i][j] == 'X') grids--; } } int t = Tsec - (abs(dr - sr) + abs(dc-sc)); if (t < 0 || (t & 1) || grids < Tsec) puts("NO"); else if (escapeMaze()) puts("YES"); else puts("NO"); } return 0; }
版权声明:笔者靖心脏,景空间地址:http://blog.csdn.net/kenden23/,只有经过作者同意转载。