HDOJ_1010 DFS 迷宫 (奇偶剪枝)
这个题目用一般的搜索无法完成,因为题目要求在指定的时间内完成,所以只好一步一步来啦,用DFS解决
但是如果这样结果会超时,网上说是用一种奇偶剪枝的方法来间断搜索时间,下面是剪枝的简单理论,一看就懂:
把map看作
0 1 0 1 0 1
1 0 1 0 1 0
0 1 0 1 0 1
1 0 1 0 1 0
0 1 0 1 0 1
从 0->1 需要奇数步
从 0->0 需要偶数步
那么设所在位置 (x,y) 与 目标位置 (dx,dy)
如果abs(x-y)+abs(dx-dy)为偶数,则说明 abs(x-y) 和 abs(dx-dy)的奇偶性相同,需要走偶数步
如果abs(x-y)+abs(dx-dy)为奇数,那么说明 abs(x-y) 和 abs(dx-dy)的奇偶性不同,需要走奇数步
理解为 abs(si-sj)+abs(di-dj) 的奇偶性就确定了所需要的步数的奇偶性!!
而 (ti-setp)表示剩下还需要走的步数,由于题目要求要在 ti时 恰好到达,那么 (ti-step) 与 abs(x-y)+abs(dx-dy) 的奇偶性必须相同
因此 temp=ti-step-abs(dx-x)-abs(dy-y) 必然为偶数!
下面是参考代码:
/* 功能Function Description: POJ-1010 开发环境Environment: vc6.0 技术特点Technique: 版本Version: 作者Author: jzjz 日期Date: 20120817 备注Notes: 迷宫搜索+奇偶剪枝 */ #include<stdio.h> #include<math.h> int time,atx,aty,n,m; char map[26][26]; bool flag; void dfs(int x,int y,int t) { if(x<0||x>=n||y<0||y>=m) return; if(flag==true||(t==0&&x==atx&&aty==y)) { flag=true; return; } int temp=t-abs(x-atx)-abs(y-aty); //剪枝 if(temp<0 || temp&1)//奇偶性剪枝 与运算 判断奇偶,偶时才行 return; map[x][y]='X'; if(map[x+1][y]!='X') { dfs(x+1,y,t-1); if(flag) return; } if(map[x][y+1]!='X') { dfs(x,y+1,t-1); if(flag) return; } if(map[x-1][y]!='X') { dfs(x-1,y,t-1); if(flag) return; } if(map[x][y-1]!='X') { dfs(x,y-1,t-1); if(flag) return; } map[x][y]='.'; } int main() { int i,j,x,y,wall; while(scanf("%d%d%d",&n,&m,&time)&&(n!=0||m!=0||time!=0)) { flag=false; wall=0; for(i=0;i<n;++i) { scanf("%s",map[i]); for(j=0;j<m;++j) { if(map[i][j]=='S') { x=i; y=j; } if(map[i][j]=='D') { atx=i; aty=j; } if(map[i][j]=='X') wall++; } } dfs(x,y,time); if(n*m-wall<=time) { printf("NO\n"); continue; } if(flag) printf("YES\n"); else printf("NO\n"); } return 0; }