ZOJ2412(DFS)

    这个题是一道非常经典的DFS,我调试了几个晚上,每天晚上调一个小时,终于调试好了。我采用了《计算机图形学》里的编码裁剪算法,再加上DFS就AC了。

    效率是并列第一名(C语言)。

    我的代码:

#include<stdio.h>

unsigned char farm[50][50];
unsigned char type[11]={9,12,3,6,10,5,13,11,7,14,15};//A-K 11种编码 
unsigned char con[4]={7,11,13,14};  //上右下左 裁边 
int der[4][2]={{-1,0},{0,1},{1,0},{0,-1}};// 上右下左 顺时针 
int wid,len;

void dfs(int x,int y)
{
   int i,a,b,tag1,tag2 ;
   /* 先把无效边裁减掉 */ 
    if(x == 0)
           farm[x][y] &=  con[0];
    if(y == len - 1)
           farm[x][y] &= con[1];
    if(x == wid - 1)
           farm[x][y] &= con[2];
    if(y == 0)
           farm[x][y] &= con[3];
           
   if(farm[x][y])//如果为0,就没必要深搜了        
   for(i = 0 ; i < 4 ; ++i)
   {
     a = x + der[i][0];
     b = y + der[i][1];
     if(a < 0 || a >= wid || b < 0 || b >= len)//越界判断 
       continue ;
     tag1 = 0 ;
     tag2 = 0 ;
     if(farm[a][b])
     {
       switch(i)// 判断是否能连接上 
       {
         case  0: tag1 = farm[a][b] & 2; tag2 = farm[x][y] & 8 ;break;         
         case  1: tag1 = farm[a][b] & 1; tag2 = farm[x][y] & 4 ;break;
         case  2: tag1 = farm[a][b] & 8; tag2 = farm[x][y] & 2 ;break;
         case  3: tag1 = farm[a][b] & 4; tag2 = farm[x][y] & 1 ;break;
       }  
       if(tag1 && tag2) //连接上了 
       {
          switch(i)//剪掉连边 
         {
            case  0: farm[x][y] &= con[0];farm[a][b] &= con[2];break;         
            case  1: farm[x][y] &= con[1];farm[a][b] &= con[3];break;
            case  2: farm[x][y] &= con[2];farm[a][b] &= con[0];break;
            case  3: farm[x][y] &= con[3];farm[a][b] &= con[1];break;
         }
        dfs(a,b);
       } 
    } 
  } 
   farm[x][y] = 0 ; //都搜了,要置0 
   return ;     
}

int main()
{
    int i,j,cnt; 
    char c;
    while(scanf("%d%d",&wid,&len))
    {
         if(wid < 0 || len < 0) break;
         for(i = 0 ; i < wid ; ++i) 
         {
               getchar();
               for(j = 0 ; j < len ; ++j)
               {
                 scanf("%c",&c);
                 farm[i][j] = type[c-'A'];      
               }  
         }  
         cnt = 0;
         for(i = 0 ; i < wid ; ++i)
         for(j = 0 ; j < len ; ++j)
             if(farm[i][j])
             {
               dfs(i,j);
               ++cnt;              
             }  
         printf("%d\n",cnt);                     
    }

  return 0;    
}
 

 由于不太好理解,所以我写了很多注释。

原文地址:https://www.cnblogs.com/HpuAcmer/p/2250467.html