• hdoj--1010<dfs+奇偶剪枝>


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1010

    题目描述:在n*m的矩阵中,有一起点和终点,中间有墙,给出起点终点和墙,并给出步数,在该步数情况下走到终点,走过的点不能再走;

    题目要点:dfs+奇偶剪枝;输入;

          本题用dfs可以做出结果,但是会超时,需要用到就剪枝,来减去大部分的可能;

    奇偶剪枝:

          方格中起点(tx,ty)和终点(dx, dy)最小步骤是minstep=abs(tx-dx)+abs(ty-dy);

          给定步数t,从起点走到终点,如果t < minstep,不可以,如果t =minstep,一部也没有多走,如果t> minstep,则多走了extra步,extra=t-minstep;

         经过推导可以证明多走的一定是偶数步,即extra一定是偶数。

          现在,如果已经走了n步,到达了(x,y)的位置,现在距离终点最小距离是L=abs(x-dx)+abs(y-dy);  现在还可以走的是 t - n 步,如果(t-n)<0,则不能走到地方,如果(t- n)-L 是奇数,则无法多走出偶数步到达指定位置,所以这样的是不行的;

           同时,本题时间卡的比较紧,使用dfs事实上是构造可行方案树,有m步最后就有2^m个叶子,所以在进入下一层dfs之前判断是否可行可以减少一大部分叶子;

    代码如下:

     1 
     2 #include<iostream>
     3 #include<math.h>
     4 
     5 using namespace std;
     6 int n,m,t,k,dx,dy;
     7     int p,q,tm;
     8     int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};//构建位置数组,遍历周围四个点;
     9 char a[8][8];
    10 void dfs(int x,int y,int count)
    11 {
    12     int temp;
    13     temp=t-count-abs(dx-x)-abs(dy-y);
    14     if(temp<0||temp%2==1)                    //判断是否有偶数步,没有就退出;
    15         return ;
    16 
    17     int tx,ty;
    18         for(int i=0;i<4;i++)                 //循环遍历周围的四个结点,先预判是否超出边界,然后判断是否找到结果,如果找到就不用在进去了;
    19         {
    20             tx=x+dir[i][0];
    21             ty=y+dir[i][1];
    22             if(a[tx][ty]=='D'&&count==t-1)
    23             {
    24                 k=1;
    25                 return ;
    26             }
    27             if(a[tx][ty]=='.'&&(tx>=0&&tx<n)&&(ty>=0&&ty<m))
    28             {
    29                 a[tx][ty]='X';
    30                 dfs(tx,ty,count+1);
    31                 a[tx][ty]='.';
    32                 if(k==1)           //如果没有确定的结果就进去dfs,出来后判断是否有结果了,这样可以减少dfs的步骤;
    33                     return ;
    34             }
    35         }
    36     
    37 }
    38 int main()
    39 {
    40     while(cin>>n>>m>>t&&n!=0||m!=0||t!=0)
    41     {
    42         tm=0;
    43         for(int i=0;i<n;i++)
    44         {
    45             for(int j=0;j<m;j++)
    46             {
    47                 cin>>a[i][j];
    48                 if(a[i][j]=='S')
    49                 {
    50                     p=i;q=j;
    51                 }
    52                 if(a[i][j]=='D')
    53                 {
    54                     dx=i;dy=j;
    55                 }
    56                 if(a[i][j]=='X')
    57                     tm++;
    58             }
    59         }
    60         k=0;
    61         if(n*m-tm<=t)     //开始判断是否有足够的空来走,没有就直接跳过dfs;
    62         {
    63             printf("NO
    ");
    64             continue;
    65         }
    66         dfs(p,q,0);
    67         if(k==1)
    68             printf("YES
    ");
    69         else
    70             printf("NO
    ");
    71     }
    72     return 0;
    73 }
    View Code

    顺便贴几个dfs的题目

    hdoj:  1010  1015  1016  1045  1175  1181  1241  1272  1421  1455  1518  1728

  • 相关阅读:
    C语言第四章
    C第三章,指代数据
    DES+MD5加密
    时间选择器
    百度地图定位
    Httputils请求网络数据
    xStream解析xml文件
    pulltorefresh
    slidingmenu的应用
    Duutils创建数据库
  • 原文地址:https://www.cnblogs.com/by-1075324834/p/4328758.html
Copyright © 2020-2023  润新知