HDU1010——Tempter of the Bone

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
");
            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
");
        }else{
            dfs(x,y,0);
            if(flag==0)printf("NO
");
        } 
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Yvettey-me/p/4523590.html