hdu 1010——Tempter of the Bone(DFS)

来源:互联网 发布:php提交按钮代码 编辑:程序博客网 时间:2024/06/04 22:57

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1010

解题思路:dfs和bfs都可以。有意思的是这道题并不是能在 t 时间内到达就输出YES,而是要刚好在 t 时刻到达出口才满足题目要求。单用深搜或广搜会超时,所以还要用到剪枝,剪枝包括奇偶剪枝和边界剪枝,本题用到奇偶剪枝

奇偶剪枝:

0  1  0  1  0
1  0  1  0  1
0  1  0  1  0
1  0  1  0  1
0  1  0  1  0

把坐标之和表示成奇偶性,则:

从任意0到任意1,需要走奇数步;

从任意0到任意0,需要走偶数步。

判断终点横纵坐标之和 - 起点横纵坐标之和的奇偶性是否与剩余时间奇偶性相同,若不同,则永远无法在 t 时刻走到终点,所以递归之前把这种情况先剪掉,就不会TLE了

#include <stdio.h>#include <string.h>#include <stdlib.h>#include <math.h>char map[10][10];int n,m,t,flag;int sx,sy,ex,ey;int dir[4][2]={1,0,-1,0,0,1,0,-1}; //上下左右四个方向int judge(int x,int y){if(x>=0 && x<n && y>=0 && y<m && map[x][y]!='X') //除去起点return 1;return 0;}void dfs(int x,int y,int t){int i,nx,ny;if(flag) //这句判断不加上的话就会超时return ;if(t<abs(ex-x)+abs(ey-y) || t%2!=(abs(ex-x)+abs(ey-y))%2) //奇偶剪枝return ;else if(t==0) //剩余时间为0{if(x==ex && y==ey){flag=1;return ;}elsereturn ;}else{for(i=0;i<4;i++){nx=x+dir[i][0];ny=y+dir[i][1];if(judge(nx,ny)){map[nx][ny]='X';dfs(nx,ny,t-1);map[nx][ny]='.'; //回溯}}return ;}}int main(){int i,j;while(scanf("%d%d%d",&n,&m,&t),n!=0,m!=0,t!=0){for(i=0;i<n;i++)scanf("%s",map[i]);for(i=0;i<n;i++){for(j=0;j<m;j++){if(map[i][j]=='S'){map[i][j]='X'; //一定要把起点标记为Xsx=i;sy=j;}else if(map[i][j]=='D'){ex=i;ey=j;}}}flag=0;dfs(sx,sy,t);if(flag)printf("YES\n");elseprintf("NO\n");}return 0;}


原创粉丝点击