zoukankan      html  css  js  c++  java
  • (DFS)hdoj1175:连连看

    题目链接

    这道题被稍微改编当作过去年的期末上机题,也被直接放到了这次这一届的第二次练习赛。当初刚看到这道题时DFS并没有系统的学过,做起来极其费劲。现在学过之后开始实践练习,发现这道题真的是很水。

    我的DFS函数中加入了方向,和拐弯数两个参数,作为判断。(其实是放在外面当全局变量自己控制不好的借口orz),并将vi这个数组存储为到达这个位置时最少的拐弯数,这样大于vi到达这里并且vi不是初始值-1的就直接剪枝。

     1 #include<cstdio>
     2 #include<cstring>
     3 using namespace std;
     4 int a[1005][1005],n,m,vi[1005][1005],dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}},ci,flag,ei,ej;
     5 void dfs(int si,int sj,int d,int x)
     6 {
     7     if(si==ei&&sj==ej&&x<=2)//看是否成功到达终点
     8         {flag=1;return;}
     9     if(si<0||si>=n||sj<0||sj>=m||x>2||(x>vi[si][sj]&&vi[si][sj]!=-1)||a[si][sj]!=0||flag==1)//几个预先判断
    10         return;
    11     else
    12     {
    13         a[si][sj]=1;
    14         vi[si][sj]=x;//注意将vi存储为到这个位置所经历的拐弯数
    15         for(int i=0;i<4;i++)
    16         {
    17             if(i==d)dfs(si+dir[i][0],sj+dir[i][1],i,x);//有两种情况,继续沿着之前的方向前进的话拐弯数不变,不然就+1
    18             else
    19             dfs(si+dir[i][0],sj+dir[i][1],i,x+1);
    20         }
    21             a[si][sj]=0;
    22     }
    23 }
    24 int main()
    25 {
    26     while(scanf("%d%d",&n,&m))
    27     {
    28         if(n==0&&m==0)
    29             break;
    30         int i,j,si,sj;
    31         for(i=0;i<n;i++)
    32             for(j=0;j<m;j++)
    33                 scanf("%d",&a[i][j]);
    34         scanf("%d",&ci);
    35         while(ci--)
    36         {
    37             memset(vi,-1,sizeof(vi));//将数组初始化为-1这个之后不可能取到的值有助于判断
    38             scanf("%d%d%d%d",&si,&sj,&ei,&ej);
    39             si--;
    40             sj--;
    41             ei--;
    42             ej--;
    43             flag=0;
    44             if(a[si][sj]!=a[ei][ej]||(a[si][sj]==0)||a[ei][ej]==0)//如果是不需dfs就能判断的不成立情况就直接continue
    45             {
    46                 printf("NO
    ");
    47                 continue;
    48             }
    49             else
    50             {
    51                 for(i=0;i<4;i++)
    52                     dfs(si+dir[i][0],sj+dir[i][1],i,0);
    53                 if(flag)
    54                     printf("YES
    ");
    55                 else
    56                     printf("NO
    ");
    57             }
    58         }
    59     }
    60     return 0;
    61 }

    当初做起来非常困难的题目现在可以不到10分钟轻松做出来,进步的喜悦真的是难以描述。还有很多的内容需要学习与练习,继续加油!

  • 相关阅读:
    linux top详解
    软件人才必须具备的素质
    合格程序员每天每周每月每年应该做的事
    正则匹配任意字符(包括换行)
    软件测试方案
    LInux进程间的通信方式有哪儿些?
    三网融合
    php路径问题
    xp 安装SATA AHCI驱动
    进程与线程的区别
  • 原文地址:https://www.cnblogs.com/quintessence/p/6029348.html
Copyright © 2011-2022 走看看