http://acm.hdu.edu.cn/showproblem.php?pid=1010
这道题讲的是起点是S要到达D点是否可以恰好在规定的T时间到达,而且走的路径不能返回。
解题思路:用的是深搜,搜索是否在T时间是正好到达D点
剪枝:奇偶剪枝,访问范围不能超过图的范围,访问过了或者遇到X都是不能继续访问了。
难点:状态改变有坐标和时间,以时间为判断结束标识。
#include <iostream> #include <cstdio> #include <cstring> #include<cmath> using namespace std; void dfs(int x,int y,int t) ; int n, m,T; int vis[1001][1001],x,y,xx,yy; char G[1001][1001]; int cnt, flag; int dx[]={0,0,1,-1}; int dy[]={1,-1,0,0}; struct point{ int x,y; }; void dfs(int x,int y,int t) { if(flag==1)return;//提前结束 if(t==T){ if(G[x][y]=='D'){ flag=1; printf("YES\n"); return; } }else{ for(int i=0;i<4;i++){ int xt=x+dx[i]; int yt=y+dy[i]; if(xt>=n||xt<0) continue; if(yt>=m||yt<0) continue; if(vis[xt][yt]||G[xt][yt]=='X') continue; // if(G[xt][yt]=='D')continue; vis[xt][yt]=1; dfs(xt,yt,t+1); vis[xt][yt]=0; } } } int main() { while(~scanf("%d%d%d", &n, &m,&T)&&n!=0&&m!=0&&T!=0) { cnt = flag = 0; for(int i=0;i<n;i++){ scanf("%s",G[i]); } memset(vis, 0, sizeof(vis)); for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ if(G[i][j]=='S'){ x=i;y=j; }else if(G[i][j]=='D'){ xx=i;yy=j; } } } int len=abs(xx-x)+abs(yy-y); vis[x][y]=1; if(T<len||(T-len)%2!=0){//奇偶剪枝(其实道理很明白啊,就是a到b的距离肯定是d(min)+2*k(k属于正整数)) printf("NO\n"); }else{ dfs(x,y,0); if(flag==0)printf("NO\n"); } } return 0; }