首页 > 代码库 > hdu-1010 Tempter of the Bone
hdu-1010 Tempter of the Bone
http://acm.hdu.edu.cn/showproblem.php?pid=1010
题意:在n*m的地图上,标记为S的为狗狗的起点,D为门,问能否恰好以给定t的时间到达D,能就输出YES,否则NO,每个点只能走一次。
思路:dfs问题,找到一条长度恰好为t的路径,不一定是最短路路径,所以不能单纯用bfs。
但是 一般dfs会超时,所以要剪枝,这里主要用到奇偶性剪枝,参考链接:
http://baike.baidu.com/view/7789287.htm?fr=alad
http://www.slyar.com/blog/depth-first-search-even-odd-pruning.html
下面是优化后的代码:46ms
#include <iostream> #include <cstring> #include <cstdio> #include <cmath> using namespace std; char map[9][9]; int n,m,t,di,dj; bool escape; int dir[4][2]={{0,-1},{0,1},{1,0},{-1,0}}; void dfs(int si,int sj,int cnt) { if(cnt>10000) return; if(escape) return; if(si>n||sj>m||si<=0||sj<=0) return; if(cnt==t&&si==di&&sj==dj) escape=1; //找到恰好为t的路径 if(escape) return; if(cnt>=t) return; //如果当前步数比t大 int i,temp; temp=(t-cnt)-abs(si-di)-abs(sj-dj); //奇偶性剪枝,t-cnt是表示剩余的步数,后面两个绝对值之和是表示当前点到终点的最短路径 if(temp<0||temp&1) return; //结果不能小于0或者为基数,因为上面的差一定为偶数才有解。 for(i=0;i<4;i++){ if(map[si+dir[i][0]][sj+dir[i][1]]!='X') { map[si+dir[i][0]][sj+dir[i][1]]='X'; dfs(si+dir[i][0],sj+dir[i][1],cnt+1); map[si+dir[i][0]][sj+dir[i][1]]='.'; } } return; } int main() { int i,j,si,sj; while(cin>>n>>m>>t) { if(n==0&&m==0&&t==0) break; int wall=0; for(i=1;i<=n;i++) for(j=1;j<=m;j++) { cin>>map[i][j]; if(map[i][j]=='S') { si=i; sj=j; } else if(map[i][j]=='D') { di=i; dj=j; } else if(map[i][j]=='X') wall++; } if(n*m-wall<=t) //如果地图全部能够走的步数加起来都小于等于t,表示一定不能达到。 { cout<<"NO"<<endl; continue; } escape=0; map[si][sj]='X'; dfs(si,sj,0); if(escape) cout<<"YES"<<endl; else cout<<"NO"<<endl; } return 0; }
hdu-1010 Tempter of the Bone
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。