寻找连通域
http://www.mrluoyi.com/blog/2012/03/connected-domain/#respond
尋找一副二值圖像中的連通域。全圖遍歷+DFS深度優(yōu)先搜索。
示例輸入: 5 5 0 0 0 0 1 0 1 1 0 1 0 1 0 0 1 1 1 1 0 1 1 1 0 0 1 示例輸出: The number of connected domains is: 2 Connected domains are labeled as below: 0 0 0 0 2 0 3 3 0 2 0 3 0 0 2 3 3 3 0 2 3 3 0 0 2第一種辦法比較直觀,是遞歸的辦法,代碼如下:
#include<stdio.h>//by Yi Luo (03/08/2012)#define max 500 int I[max][max]; int n, m;// size = n*m int num = 0;const int direction[][2]={{1,0},{0,-1},{0,1},{-1,0}};bool check(int x, int y){if (x >= 0 && x < n && y >= 0 && y < m && I[x][y] == 1){return true;}else{return false;} }bool DFS(int x, int y, int label){if (1 != I[x][y]) {return false;}else{I[x][y] = label;for (int i = 0; i < 4; i++){if (check(x + direction[i][0], y + direction[i][1])){DFS(x + direction[i][0], y + direction[i][1], label);}} }return true; }int main(void) {scanf("%d%d", &n, &m);for (int i = 0; i < n; ++i){for (int j=0; j< m; j++){scanf("%d", &I[i][j]);} }int label = 2; for (int i = 0; i < n; ++i){for (int j = 0; j < m; ++j){if (DFS(i, j, label)){label++;}}}num = label - 2;printf("\n\nThe number of connected domains is: %d\n", num);printf("Connected domains are labeled as below:\n\n");for (int i = 0; i < n; ++i){for (int j=0; j< m; j++){printf("%d ", I[i][j]);} printf("\n");}getchar();getchar();return 0; }剛剛又學(xué)到了一種新的辦法,就是直接掃描的辦法,比較巧妙。對(duì)于四領(lǐng)域的情況,主要是考察每個(gè)前景點(diǎn)的左邊、上邊兩個(gè)點(diǎn)的情況:
1、如果左邊和上邊都有標(biāo)記過的前景點(diǎn),則選擇二者標(biāo)號(hào)更小的作為當(dāng)前點(diǎn)的標(biāo)記,并將之前所有的大號(hào)改成小號(hào);
2、如果只有左邊是標(biāo)記過的點(diǎn),則將當(dāng)前點(diǎn)和其左邊點(diǎn)標(biāo)號(hào)一致;
3、如果只有上邊是標(biāo)記過的點(diǎn),則和上面的點(diǎn)標(biāo)號(hào)一致;
4、如果左邊和上邊都沒有標(biāo)記過的點(diǎn),則當(dāng)前前景點(diǎn)新開一個(gè)標(biāo)號(hào)。
代碼如下:
總結(jié)
- 上一篇: 从给定的N个正数中选取若干个数之和最接近
- 下一篇: google面试题