http://acm.hdu.edu.cn/showproblem.php?pid=1010
题意很好理解,不是最短路,而是dfs,虽然地图不算大,稍微注意一点的dfs也能险过,可是700+ms和78ms一对比仍是让人难受php
对dfs的剪枝处理,实际上就是一个逻辑推理ios
面对整个地图我能够作出如下判断若是 n * m - wall <= t那就必定say NO优化
n * m 是整个地图的大小,wall是地图中墙的个数相减以后就是最多能够走的步数,之因此取到等号是由于在第0秒的时候,已经走了一个地方了(起点)spa
这就是路径剪枝
接下来看一看奇偶剪枝:code
奇偶剪枝:
把矩阵标记成以下形式
0,1,0,1,0
1,0,1,0,1
0,1,0,1,0
1,0,1,0,1blog
起点和终点奇偶不一样——要走奇数步,奇偶相同——要走偶数步,与路径剪纸不一样的是奇偶剪纸能够放到dfs里,对dfs的优化效果也很好get
进而能够推出下面的关系(他们之间的关系有一个就是奇数-奇数=偶数,偶数-偶数=偶数,因此若是temp是奇数,那么就say no)string
令 temp = (t - step) - (abs(sx - ex) + abs(sy - ey));
abs(sx - ex) + abs(sy - ey)到达终点最少还要的步数
t - step 还剩下的步数
1——》temp < 0 确定到不了了return
2——》temp > 0
(1)temp是奇数 --》绕道多走必然多走偶数步-出去一步,进来以不,
//例如走a b你能够试一试不管怎么走再回到正轨上确定多走偶数步因此retur
(2)temp是偶数--》能够正常dfs
it
#include <iostream> #include <cstdio> #include <string> #include <string.h> using namespace std; const int maxn = 10; int mp[10][10]; int vis[10][10]; int foot[4][2] = {1,0,-1,0,0,1,0,-1}; int n,m,t,sx,sy,ex,ey,wall; int retflag; void init() { memset(mp,0,sizeof(mp)); memset(vis,0,sizeof(vis)); retflag = 0; wall = 0; } void dfs(int x,int y,int step) { if(x == ex && y == ey) { if(step == t) { retflag = 1; } return; } if(retflag)return; int temp = (t - step) - (abs(sx - ex) + abs(sy - ey)); if(temp < 0 || temp & 1) { return; } for(int i = 0;i < 4;i++) { int nx = x + foot[i][0]; int ny = y + foot[i][1]; if(nx >= 0 && nx < n && ny >= 0 && ny < m && !vis[nx][ny] && mp[nx][ny] != 1) { vis[nx][ny] = 1; dfs(nx,ny,step + 1); vis[nx][ny] = 0; } } } int main() { char ch; while(~scanf("%d%d%d",&n,&m,&t)) { getchar(); if(!n && !m && !t)break; init(); for(int i = 0;i < n;i++) { for(int j = 0;j < m;j++) { scanf("%c",&ch); if(ch=='X'){mp[i][j] = 1;wall++;} if(ch=='S') { sx = i; sy = j; vis[i][j] = 1; } if(ch=='D') { ex = i; ey = j; } if(ch=='.')mp[i][j] = 0; } getchar(); } if(n * m - wall <= t) { printf("NO\n"); continue; } dfs(sx,sy,0); if(retflag)printf("YES\n"); else printf("NO\n"); } return 0; }