zoukankan      html  css  js  c++  java
  • UVA 572 -- Oil Deposits(DFS求连通块+种子填充算法)

    UVA 572 -- Oil Deposits(DFS求连通块)

       图也有DFS和BFS遍历,由于DFS更好写,所以一般用DFS寻找连通块。

      下述代码用一个二重循环来找到当前格子的相邻8个格子,也可用常量数组或者写8条DFS调用。

      下述算法是:种子填充(floodfill)

      两种连通区域

       四连通区域:从区域内一点出发,可通过上、下、左、右四个方向的移动组合,在不越出区域的前提下,能到达区域内的任意像素

      八连通区域:从区域内每一像素出发,可通过八个方向,即上、下、左、右、左上、右上、左下、右下移动的组合,在不越出区域的前提下,能到达区域内的任意像素。

     

      基本原理

      从多边形区域内部的某一像素点(称为种子)开始,由此出发找到区域内的其它所有像素。

      采用的边界定义

      区域边界上所有像素均具有某个特定的颜色值,区域内部所有像素均不取这一特定颜色,而边界外的像素则可具有与边界相同的颜色值。

      算法的执行过程:

      从(x,y)开始,先检测该点的颜色,若它与边界色和填充色均不相同,则用填充色填充该点。然后检测相邻位置,以确定它们是否是边界色和填充色,若不是,则填充该相邻点。直到检测完区域边界范围内的所有像素为止。
       从当前点检测相邻像素的方法:四连通或八连通
       从四个方向寻找下一个像素,称为四向算法(只能填充四连通区域);
       从八个方向寻找下一个像素,称为八向算法(可以填充八连通区域和四连通区域)。

      四连通区域的种子填充递归算法:

     1 void ZhongZiTC4 (int seedx, int seedy, int fcolor, int bcolor)
     2 {    
     3      int current = getpixel (seedx, seedy);
     4      if ((current != bcolor) && (current != fcolor))
     5      {     putpixel (seedx, seedy, fcolor);
     6      ZhongZiTC4 (seedx+1, seedy, fcolor, bcolor);  //
     7      ZhongZiTC4 (seedx–1, seedy, fcolor, bcolor);  //
     8      ZhongZiTC4 (seedx, seedy+1, fcolor, bcolor);  //
     9      ZhongZiTC4 (seedx, seedy–1, fcolor, bcolor);  //
    10      }
    11 } 

    UVA 572代码:

     1 #include<iostream>
     2 #include<cstring>
     3 using namespace std;
     4 const int maxn = 100+5;
     5 char deposits[maxn][maxn];
     6 int id[maxn][maxn];
     7 int rm,cm;
     8 void dfs(int r,int c,int cnt)
     9 {
    10     ///判断是否出界
    11     if(r<0 || r>=rm || c<0 || c>=cm) return;
    12     ///临界条件
    13     if(deposits[r][c] == '*') return;
    14     if(id[r][c]) return;
    15 
    16     id[r][c] = cnt;
    17     for(int i=-1;i<=1;i++)
    18         for(int j=-1;j<=1;j++)
    19             if(i!=0 || j!=0) dfs(r+i,c+j,cnt);
    20 
    21 }
    22 
    23 int main()
    24 {
    25 
    26     while(cin>>rm>>cm && rm && cm)
    27     {
    28         for(int i=0;i<rm;i++) cin>>deposits[i];
    29         int cnt=0;
    30         memset(id,0,sizeof(id));
    31         for(int i=0;i<rm;i++)
    32             for(int j=0;j<cm;j++)
    33             {
    34                 if(!id[i][j] && deposits[i][j]=='@')///没有编号
    35                     dfs(i,j,++cnt);
    36             }
    37         cout<<cnt<<endl;
    38 
    39     }
    40     return 0;
    41 }

  • 相关阅读:
    模板
    常用文件的位置
    前端基础之JavaScript
    CSS属性相关
    前端之CSS
    jQuery方法及使用
    前端-HTLM
    前端之BOM与DOM-JQuery
    视图-触发器-事务-存储过程-函数
    Navicat-pymysql-sql注入问题
  • 原文地址:https://www.cnblogs.com/yxh-amysear/p/8450384.html
Copyright © 2011-2022 走看看