zoukankan      html  css  js  c++  java
  • DOJ 1010 Tempter of the Bone (DFS)

    深度优先算法入门的一道非常好的题目,

    还考虑到了剪枝

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

     1 //这个代码是没有考虑任何剪枝的
     2 //将所以情况都遍历了一遍,
     3 //提交的时候是会超时的  Time Limit Exceeded
     4 #include<iostream>
     5 #include<string.h>
     6 using namespace std;
     7 
     8 #define MAX 10
     9 char mapz[MAX][MAX];
    10 int N,M,T;
    11 int dx, dy;
    12 bool escape;
    13 
    14 void dfs(int sx, int sy,int t)
    15 {
    16     if(sx <=0 || sx >N || sy <= 0 || sy > M)
    17         return;
    18     if(escape == true ||( sx == dx && sy ==dy && t == 0 ))
    19     {
    20         escape =true;
    21         return;
    22     }    
    23     mapz[sx][sy] = 'X';
    24     if(mapz[sx+1][sy] != 'X')
    25     {
    26         dfs(sx+1,sy,t-1);
    27         if(escape) return;
    28     }
    29     if(mapz[sx][sy+1] != 'X')
    30     {
    31         dfs(sx,sy+1,t-1);
    32         if(escape) return;
    33     }
    34     if(mapz[sx-1][sy] != 'X')
    35     {
    36         dfs(sx-1,sy,t-1);
    37         if(escape) return;
    38     }
    39     if(mapz[sx][sy-1] != 'X')
    40     {
    41         dfs(sx,sy-1,t-1);
    42         if(escape) return;
    43     }
    44     mapz[sx][sy] = '.';
    45 }
    46 
    47 
    48 int main()
    49 {
    50     int sx,sy,i,j;
    51     while(scanf("%d%d%d",&N,&M,&T)!=EOF)
    52     {
    53         if(N == 0&& M == 0 &&T == 0)
    54          continue;
    55          getchar();
    56         for(i=1;i<=N;i++)
    57         {
    58             for(j=1;j<=M;j++)
    59             {
    60                 scanf("%C", &mapz[i][j]);
    61                 if(mapz[i][j] == 'S')
    62                 {sx = i; sy = j;}
    63                 else if(mapz[i][j] == 'D')
    64                 {dx = i; dy = j;}
    65             }
    66             getchar();
    67         }
    68         escape =false;
    69         dfs(sx,sy,T);
    70         if(escape)
    71         printf("YES
    ");
    72         else
    73         printf("NO
    ");
    74     }
    75 }
    //接下来就要考虑剪枝了
    //每个block只能走一次
    //要求恰好某个给定的时间到达出口
    //如果可走的block的总数小于时间,将会产生什么情况?
    
    /*
    可以把map看成这样: 
    0 1 0 1 0 1 
    1 0 1 0 1 0 
    0 1 0 1 0 1 
    1 0 1 0 1 0 
    0 1 0 1 0 1 
    从为 0 的格子走一步,必然走向为 1 的格子 
    从为 1 的格子走一步,必然走向为 0 的格子 
    即: 
     0 ->1或1->0 必然是奇数步 
     0->0 走1->1 必然是偶数步 
    结论
    所以当遇到从 0 走向 0 但是要求时间是奇数的,或者, 从 1 走向 0 但是要求时间是偶数的 都可以直接判断不可达!
    
    */
    /*
    那么设所在位置 (x,y) 与 目标位置 (dx,dy)
    如果abs(dx-x)+abs(dy-y) 为偶数,则说明 abs(dx-x)+和 abs(dy-y)的奇偶性相同,需要走偶数步
    如果abs(dx-x)+abs(dy-y)为奇数,那么说明 abs(dx-x)和 abs(dy-y)的奇偶性不同,需要走奇数步
    解为 abs(dx-sx)+abs(dy-sy)的奇偶性就确定了所需要的步数的奇偶性!!
    而 (ti-setp)表示剩下还需要走的步数,由于题目要求要在 ti时 恰好到达,那么  (ti-step) 
    与 abs(x-y)+abs(dx-dy) 的奇偶性必须相同
    因此 temp=ti-step-abs(dx-x)-abs(dy-y) 必然为偶数!
    
    */
    
    #include<iostream>
    #include<string.h>
    #include<math.h>
    using namespace std;
    
    #define MAX 10
    char mapz[MAX][MAX];
    int N,M,T;
    int dx, dy;
    bool escape;
    
    void dfs(int sx, int sy,int t)
    {
        if(sx <=0 || sx >N || sy <= 0 || sy > M)
            return;
        if(escape == true ||( sx == dx && sy ==dy && t == 0 ))
        {
            escape =true;
            return;
        }    
        //------------------------------------
        int tmp = t - abs(sx-dx) - abs(sy - dy);
        if (tmp < 0|| tmp&1)
        return;                                        //这里就是奇偶性剪枝 
        //------------------------------------
        mapz[sx][sy] = 'X';
        if(mapz[sx+1][sy] != 'X')
        {
            dfs(sx+1,sy,t-1);
            if(escape) return;
        }
        if(mapz[sx][sy+1] != 'X')
        {
            dfs(sx,sy+1,t-1);
            if(escape) return;
        }
        if(mapz[sx-1][sy] != 'X')
        {
            dfs(sx-1,sy,t-1);
            if(escape) return;
        }
        if(mapz[sx][sy-1] != 'X')
        {
            dfs(sx,sy-1,t-1);
            if(escape) return;
        }
        mapz[sx][sy] = '.';        //回溯 
    }
    
    
    int main()
    {
        int sx,sy,i,j;
        while(scanf("%d%d%d",&N,&M,&T)!=EOF)
        {
            if(N == 0&& M == 0 &&T == 0)
             continue;
             getchar();
            //--------------
             int wall = 0;
            //-------------- 
            for(i=1;i<=N;i++)
            {
                for(j=1;j<=M;j++)
                {
                    scanf("%C", &mapz[i][j]);
                    if(mapz[i][j] == 'X')
                        wall++;
                    if(mapz[i][j] == 'S')
                    {sx = i; sy = j;}
                    else if(mapz[i][j] == 'D')
                    {dx = i; dy = j;}
                }
                getchar();
            }
            escape =false;
            //---------------------------------------- 这里是  可走的block的总数小于时间
            if(N*M-wall <= T)
            {
                printf("NO
    ");
                continue;        
            }
            //---------------------------------------- 
            dfs(sx,sy,T);
            if(escape)
            printf("YES
    ");
            else
            printf("NO
    ");
        }
    }
    //
    void DfsSerch(int x,int y,int step)
    {
       int temp;
       temp=ti-step-abs(dx-x)-abs(dy-y);
       if (temp<0||temp%2==1) return;
       int tx,ty;
       for(int i=0;i<4;i++)  //四个方向探索 上下左右走 
      {
          tx=x+dir[i][0];   ty=y+dir[i][1];
          if (a[tx][ty]=='D'&&step==ti-1)
          { flag=1;   return ; }
          if(a[tx][ty]=='.'&&(tx>=0&&tx<n)&&(ty>=0&&ty<m))
          {
             a[tx][ty]='X';  //标记访问 
             DfsSerch(tx,ty,step+1);
             a[tx][ty]='.';  //回溯取消标记
             if(flag==1) return;//找到直接返回
          }
       }
    }
  • 相关阅读:
    Spring IoC
    常见切入点表达式的例子(aop execution 表达式 )
    数据结构与算法(2)栈、中缀表达式、递归
    数据结构与算法(1)稀疏数组、队列、链表
    airflow实践
    head first 设计模式笔记13-与设计模式相处,剩下的模式,模式的分类
    head first 设计模式笔记12-复合模式
    head first 设计模式笔记11-代理模式
    head first 设计模式笔记10-状态模式
    WebDriver自动化测试常用处理方法
  • 原文地址:https://www.cnblogs.com/Lee-geeker/p/3233597.html
Copyright © 2011-2022 走看看