• 深搜--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;
    }
    

      

  • 相关阅读:
    Java知识之运算符篇
    对List取交集、联集及差集
    SQL in与exists的执行效率比较
    SQLServer数据集合的交、并、差三种集合运算
    获取外网IP
    SQL语句优化技术分析
    高并发下的获取ID解决方案
    获取数据库里面所有自增类型的最大值
    锁的概述
    项目管理心得:一个项目经理的个人体会、经验总结(转)
  • 原文地址:https://www.cnblogs.com/wsyxy/p/4279531.html
Copyright © 2020-2023  润新知