zoukankan      html  css  js  c++  java
  • hdu1010-Tempter of the Bone-(dfs+奇偶剪枝)

    http://acm.hdu.edu.cn/showproblem.php?pid=1010

    翻译:有只狗被困了,S是起点,D是门,W是墙不能走,‘ . ’是可以走的路,走一次就会在1秒内坍塌,也就是不能停留也不能走回头路,门只在第T秒打开,问是否能逃命?

    解题:一开始以为是三维bfs,但是地图上的时间维度是错误的,因为走过一次地面坍塌,只能有一个时间维度。百度找了居然一个bfs都没有,不得不用dfs,无限超时,甚至记忆化搜索也超时。见识到了高端的剪枝。

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<math.h>
    #include<string>
    #include<map>
    #include<queue>
    #include<stack>
    #include<set>
    #define ll long long
    #define inf 0x3f3f3f3f
    using namespace std;
    
    bool vis[10][10];
    char a[10][10];
    int d[4][2]={ {-1,0}, {1,0}, {0,-1}, {0,1} };///上下左右
    
    int n,m,T,cnt;
    bool flag;
    struct node
    {
        int x;
        int y;
        int t;
    };
    node door,start;
    
    
    void dfs(int x,int y,int t)///当前用了多少时间
    {
        if( x==door.x && y==door.y && t==door.t )
        {
            flag=true;
            return ;
        }
    
        for(int i=0;i<4;i++)
        {
            int cha=T-t-abs(door.x-x)-abs(door.y-y);///核心代码
    
            int xx=x+d[i][0];
            int yy=y+d[i][1];
            int tt=t+1;
            if( !flag && xx>=0 && xx<n && yy>=0 && yy<m && !vis[xx][yy] && (a[xx][yy]=='.'||a[xx][yy]=='D') && cha>=0 && cha%2==0 )
            {
                vis[xx][yy]=true;
                dfs(xx,yy,tt);
                vis[xx][yy]=false;
            }
        }
    
    }
    
    int main()///HDU1010
    {
        while(scanf("%d%d%d",&n,&m,&T) && (n+m+T) )
        {
            memset(a,0,sizeof(a));
            memset(vis,false,sizeof(vis));
            flag=false;
    
            for(int i=0;i<n;i++)
                scanf("%s",a[i]);
            for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
            {
                if( a[i][j]=='D' )///终点
                    door.x=i,door.y=j,door.t=T;
                if( a[i][j]=='S' )///起点
                {
                    start.x=i,start.y=j,start.t=0;
                    vis[ start.x ][ start.y ] = true;
    
                }
            }
            dfs( start.x,start.y,0 );
            if(flag)
                printf("YES
    ");
            else
                printf("NO
    ");
        }
    
        return 0;
    }

    dfs内,x和y表示当前坐标,t表示当前花了多少时间。

    当前步数到终点的最短距离:abs(door.x-x)+abs(door.y-y)

    还需要花的时间:T-t

    走最短路的话还剩余的时间:cha = T - t - abs(door.x-x) + abs(door.y-y)

    在没有障碍的情况下,cha至少要等于0,如果有障碍,cha要大于0,剪枝剪掉那些 就算没障碍走最短路也走不到的情况

    奇偶剪枝:

    举例:

    0 1 0 1 

    1 0 1 0

    0 0 1

    1 0 1 0

    假设红色1要走到蓝色1,最短只需要走2步,但是现在有4步,必须绕远,绕过粉色1和粉色0走到蓝色1,如果是3步,怎么走都走不到。

  • 相关阅读:
    AOP在Spring Boot中如何使用
    拦截器在Spring Boot中如何使用
    跨域在Spring Boot中如何处理
    @ControllerAdvice
    文件上传之Spring Boot整合web层
    Git和GitHub
    Spring Boot 整合web层之JSON,gson,fastjson的使用
    Spring boot整合视图层
    Spring Boot中的parent是什么?
    网页自动化,验证码识别函数,深度学习训练
  • 原文地址:https://www.cnblogs.com/shoulinniao/p/11173688.html
Copyright © 2011-2022 走看看