UVA 572 -- Oil Deposits(DFS求連通塊+種子填充算法)
阿新 • • 發佈:2018-02-16
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求連通塊+種子填充算法)