1. 程式人生 > >UVA 572 -- Oil Deposits(DFS求連通塊+種子填充算法)

UVA 572 -- Oil Deposits(DFS求連通塊+種子填充算法)

string pos .net 連通塊 dep tpi zhong deposit amp

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 }

技術分享圖片

UVA 572 -- Oil Deposits(DFS求連通塊+種子填充算法)