深搜--Tempter of the Bone hdu1010

这道题磨了我一个下午,虽然在大神帮助下完成,要注意的东西太多,之前还用了宽搜,那是每看懂题目意思,宽搜是找到一条最短路,而这道题不一定是最短路,要在规定的时间到达,换句话说就是有规定的步数,走了的不能再走。

写题中遇到以下几个问题:

1.对于深搜还是没有完全理解,由于是递归,所以每次的函数体应该都是一样的,之前把不该改变的起点步数清零放在递归函数里,导致错误。

2.对于我之前有点画蛇添足,我又加了个结构体,存迷宫每个点的横纵坐标和信息,然后我在递归结束条件那里直接判断的,但是我在赋值又没有对每个点赋值,导致出错,太粗心了。看下面的错误!!

typedef struct dd{
    int a,b;
    char sr;
}dd;

bool dfs(dd t,int dis){
    if((t.sr=='D')&&(dis==ti))
        return true;



for(int i=0;i<4;i++){
  
         s.a=t.a+x[i];
        s.b=t.b+y[i];//少了一个s.sr=maze[s.a][s.b],太粗心拉
}

  

 3.这题的特殊是在递归时返回上层应返回可不可行,而不仅仅是继续搜下去,所以有如下:

 if(dfs(s,dis+1))
                return true;

  

 4.全部完成了以后还是超时,要剪枝!由曼哈顿距离,总的耗时=曼哈顿距离+多余的路,并且多余的路一定是个偶数,否则不能到达。曼哈顿距离=|起点横坐标-终点横坐标|+|起点纵坐标-终点纵坐标|。然后这题就好啦><

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<queue>
#include<math.h>
#include<algorithm>
using namespace std;
int x[4]={-1,0,0,1};
int y[4]={0,-1,1,0};
char maze[10][10];
int vis[10][10];
int ti,n,m;
typedef struct dd{
    int a,b;
    char sr;
}dd;
dd st,en;
bool dfs(dd t,int dis){
    if((maze[t.a][t.b]=='D')&&(dis==ti))//之前在这犯错误,改了一下
        return true;
    if(dis>ti)
        return false;
    dd s;
    for(int i=0;i<4;i++){
        s.a=t.a+x[i];
        s.b=t.b+y[i];
        if(s.a>=0&&s.a<n&&s.b>=0&&s.b<m&&maze[s.a][s.b]!='X'&&!vis[s.a][s.b]){
            vis[s.a][s.b]=1;
            if(dfs(s,dis+1))
                return true;
            vis[s.a][s.b]=0;
        }
    }
    return false;
}
int main(){
    while(scanf("%d%d%d",&n,&m,&ti)!=EOF){
        if(n==0&&m==0&&ti==0)
            break;
        getchar();
        memset(vis,0,sizeof(vis));
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++)
                scanf("%c",&maze[i][j]);
            getchar();
        }
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(maze[i][j]=='S'){
                    st.sr=maze[i][j];
                    st.a=i;
                    st.b=j;
                }
                else if(maze[i][j]=='D'){
                    en.a=i;
                    en.b=j;
                }
            }
        }
        vis[st.a][st.b]=1;
        if(((ti-(st.a-en.a+st.b-en.b))%2==0)&&dfs(st,0))//剪枝,否则超时
            cout<<"YES"<<endl;
        else
            cout<<"NO"<<endl;
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/wsyxy/p/4279531.html