题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=1010
题目意思是讲有一只狗要吃骨头,结果进入了一个迷宫陷阱,迷宫里每走过一个地板费时一秒,该地板 就会在下一秒塌陷,所以你不能在该地板上逗留。迷宫里面有一个门,只能在特定的某一秒才能打开,让狗逃出去。现在题目告诉你迷宫的大小和门打开的时间,问你狗可不可以逃出去,可以就输出YES,否则NO。
搜索时要用到的剪枝:
1.如果当前时间即步数(step) >= T 而且还没有找到D点,则剪掉。
2.设当前位置(x, y)到D点(dx, dy)的最短距离为s,到达当前位置(x, y)已经花费时间(步数)step,那么,如果题目要求的时间T - step < s,则剪掉。
3. 对于当前位置(x, y),如果,(T-step-s)是奇数,则剪掉(奇偶剪枝)。
4.如果地图中,可走的点的数目(xnum) < 要求的时间T,则剪掉(路径剪枝)
#include<stdio.h> #include<stdlib.h> int n,m,ex,ey,t; int success; char maze[10][10]; void dfs(int stx,int sty,int dt) { if(stx<=0||stx>n||sty<=0||sty>m) return ; if(stx==ex&&sty==ey&&dt==t) { success=1; return ; } int temp=(t-dt)-abs(ex-stx)-abs(ey-sty); if(temp<0||temp&1) return ; if(maze[stx][sty+1]!='X') { maze[stx][sty+1]='X'; dfs(stx,sty+1,dt+1); maze[stx][sty+1]='.'; } if(maze[stx][sty-1]!='X') { maze[stx][sty-1]='X'; dfs(stx,sty-1,dt+1); maze[stx][sty-1]='.'; } if(maze[stx+1][sty]!='X') { maze[stx+1][sty]='X'; dfs(stx+1,sty,dt+1); maze[stx+1][sty]='.'; } if(maze[stx-1][sty]!='X') { maze[stx-1][sty]='X'; dfs(stx-1,sty,dt+1); maze[stx-1][sty]='.'; } } int main(void) { int stx,sty,wall,i,j; while(scanf("%d%d%d",&n,&m,&t)==3&&(n+m+t)) { getchar(); wall=0; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { scanf("%c",&maze[i][j]); if(maze[i][j]=='S') { stx=i; sty=j; } else if(maze[i][j]=='D') { ex=i; ey=j; } else if(maze[i][j]=='X') wall++; } getchar(); } success=0; maze[stx][sty]='X'; if(n*m-wall<=t) printf("NO "); else { dfs(stx,sty,0); if(success) printf("YES "); else printf("NO "); } } return 0; } 代码 #include<stdio.h> char maze[10][10]; void dfs(int stx,int sty,int dt) int main(void) 什么是奇偶剪枝?把矩阵看成如下形式: 所以当遇到从 0 走向 0 但是要求时间是奇数的或者 从 1 走向 0 但是要求时间是偶数的,都可以直接判断不可达! 比如有一地图:
要求从S点到达D点,此时,从S到D的最短距离为s = abs ( dx - sx ) + abs ( dy - sy )。 如果地图中出现了不能经过的障碍物:
此时的最短距离s' = s + 4,为了绕开障碍,不管偏移几个点,偏移的距离都是最短距离s加上一个偶数距离。 就如同上面说的矩阵,要求你从0走到0,无论你怎么绕,永远都是最短距离(偶数步)加上某个偶数步;要求你从1走到0,永远只能是最短距离(奇数步)加上某个偶数步。 |