zoukankan      html  css  js  c++  java
  • hdu Tempter of the Bone

    很典型的dfs题,但是涉及到很多的剪枝 。

    奇偶剪枝:
    是数据结构的搜索中,剪枝的一种特殊小技巧。
    现假设起点为(sx,sy),终点为(ex,ey),给定t步恰好走到终点,
    s        
    |        
    |        
    |        
    + e
     
    如图所示(“|”竖走,“—”横走,“+”转弯),易证abs(ex-sx)+abs(ey-sy)为此问题类中任意情况下,起点到终点的最短步数,记做step,此处step1=8;
      
    s  
      +  
    | +      
    |        
    + e
     
    如图,为一般情况下非最短路径的任意走法举例,step2=14;
    step2-step1=6,偏移路径为6,偶数(易证);
    故,若t-[abs(ex-sx)+abs(ey-sy)]结果为非偶数(奇数),则无法在t步恰好到达;
    返回,false;
    反之亦反。
    奇偶路径的大概意思就是:从初始位置能到达目标位置的任一路径长度  -   初始位置到目标位置的最短长度=偶数
    #include"iostream"
    #include"stdio.h"
    #include"algorithm"
    #include"queue"
    #include"string.h"
    #include"string"
    #define mx 105
    using namespace  std;
    char maze[mx][mx];
    int n,m,T,sx,sy,ex,ey;
    int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
    bool flag;
    bool  judge(int x,int y)
    {
        if(x>=0&&x<n&&y>=0&&y<m&&maze[x][y]=='.') return true;
        return false;
    }
    void dfs(int  x,int y,int t)
    {
        if(t>T||flag) return;
        if(t==T&&x==ex&&y==ey) {flag=true;return;}
        int temp=abs(x-ex)+abs(y-ey);//当前位置到目标位置的最短路径
        temp=T-t-temp;
        if(temp%2) return;//奇偶剪枝,不加这个一直tle也是醉了 。
        for(int i=0;i<4;i++)
        {
            int dx=x+dir[i][0];
            int dy=y+dir[i][1];
            if(judge(dx,dy))
            {
                maze[dx][dy]='X';
                dfs(dx,dy,t+1);
                maze[dx][dy]='.';
            }
        }
    }
    int main()
    {
    
        int i,j,blocks;
        while(cin>>n>>m>>T,n&&m&&T)
        {
            flag=false;blocks=0;
            for(i=0;i<n;i++)
            {
                for(j=0;j<m;j++)
                {
                    cin>>maze[i][j];
                    if(maze[i][j]=='S')
                    {
                        sx=i;sy=j;maze[i][j]='X';
                    }
                    else if(maze[i][j]=='D')
                    {
                        ex=i;ey=j;maze[i][j]='.';
                    }
                    else if(maze[i][j]=='X') blocks++;
                }
            }
            if(n*m-blocks-1>=T)//如果给定的时间数比能走的格子数还要大的话,就肯定不满足条件了
            dfs(sx,sy,0);
            if(flag) cout<<"YES"<<endl;
            else  cout<<"NO"<<endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    面试官:Redis 有哪些拓展方案?
    面试官:为什么要合并 HTTP 请求?
    Java 调用第三方接口,实战来了!
    Java 如何模拟真正的并发请求?
    如何搭建一台永久运行的个人服务器?试试这个黑科技!
    vs2005 sp1 出来啦!!
    2007年第一帖
    xp pro sp2支持多个用户同时终端连接
    msn中实现 "添加一个活动或游戏邀请"
    softether
  • 原文地址:https://www.cnblogs.com/acm-jing/p/4435143.html
Copyright © 2011-2022 走看看