Floodfill——漫水填充法(也称种子填充法)
简单来说就是求一个图中独立子图的个数并将其描述出不同的状态。
Floodfill在计算机图形学有着非常广泛的运用,比如图像分割、物体识别之类。
基于Floodfill算法的实现例子有Windows下“画图”软件的油漆桶工具,photoshop的魔术棒选择工具等等。
具体算法实现方法是:查找种子点周边的点,将与种子点颜色相近的点(可以设置一个阈值)入队作为
新种子,并对新入队的种子也进行同样的扩展操作,这样就选取了和最初种子相近颜色的区域。
现在有一个问题,给你一片海域的海域图,0代表海洋,1~9都表示陆地。求这片海域有多少独立的小岛,
并将他们表示成不同的状态。
代码如下:
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 int map[100][100],book[100][100],width,lenth,sum; 5 // 定义一个方向数组 6 int move[4][2] = { 7 { 0,1 },{ 1,0 },{ 0,-1 },{ -1,0 } 8 }; 9 void DFS(int x, int y, int color) 10 { 11 int k, tx, ty; 12 map[x][y] = color; // 对map[x][y]进行染色 13 for (k = 0; k < 4; k++) // 枚举四种移动方式 14 { 15 // 下一步的坐标 16 tx = x + move[k][0]; 17 ty = y + move[k][1]; 18 // 判断状态是否合法 19 if (tx < 0 || ty<0 || tx>=lenth || ty>=width) continue; 20 if (map[tx][ty] > 0 && book[tx][ty] == 0) 21 { 22 sum++; 23 book[tx][ty] = 1; 24 DFS(tx, ty, color); 25 } 26 } 27 return; 28 } 29 30 int main(void) 31 { 32 int i, j, num = 0; 33 scanf("%d %d", &lenth, &width); 34 // 读入地图 35 for (i = 0; i < lenth; i++) 36 for (j = 0; j < width; j++) 37 scanf("%d", &map[i][j]); 38 // 对每一个大于0的点尝试进行DFS染色 39 for(i=0;i<lenth;i++) 40 for (j = 0; j < width; j++) 41 { 42 if (map[i][j] > 0) 43 { 44 num--; // 颜色的编号 45 // 每发现一个小岛应该染以不同的颜色,因此递减 46 book[i][j] = 1; 47 DFS(i, j, num); 48 } 49 } 50 // 打印已经染色后的地图 51 for (i = 0; i < lenth; i++) 52 { 53 for (j = 0; j < width; j++) 54 { 55 printf("%3d", map[i][j]); 56 } 57 putchar(‘\n‘); 58 } 59 // 输出小岛的个数 60 printf("有%d个小岛\n", -num); 61 system("pause"); 62 63 return 0; 64 }
可以输入以下数据进行验证:
5 5
1 2 1 0 0
3 0 2 0 1
4 0 1 0 1
3 2 0 0 0
1 0 0 5 5
运行结果如下:
-1 -1 -1 0 0
-1 0 -1 0 -2
-1 0 -1 0 -2
-1 -1 0 0 0
-1 0 0 -3 -3
时间: 2024-10-06 00:45:18