所以说我们有一个0的空格:
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
你可以在上面画出形状。 1代表填充的细胞。
1 1 1 1 0 0 0 0
1 0 0 1 0 0 0 0
1 0 0 1 0 0 0 0
1 1 1 1 0 0 0 0
0 0 0 0 0 0 0 0
0 1 1 0 0 1 1 1
1 0 0 1 0 1 0 0
0 1 1 0 0 1 0 0
如果四向泛洪填充算法不会泄漏并填充形状外的任何单元格,则认为形状是闭合的。形状不能使用网格的边界作为其一侧。因此,如果我们用2s填充此网格中的所有闭合形状,我们将:
1 1 1 1 0 0 0 0
1 2 2 1 0 0 0 0
1 2 2 1 0 0 0 0
1 1 1 1 0 0 0 0
0 0 0 0 0 0 0 0
0 1 1 0 0 1 1 1
1 2 2 1 0 1 0 0
0 1 1 0 0 1 0 0
实现泛洪填充算法很简单,但我无法找到一种方法(以编程方式)填充网格中所有封闭的任意形状。我可以使用任何类型的算法或搜索吗?
答案 0 :(得分:1)
洪水填充算法有什么问题?它简单有效,复杂度为O(N)。
首先扫描边缘的零值,并使用标记值3填充空白区域。 然后走进内心的地方。如果您发现零单元格,则从此单元格填充洪水,值为2.
(也许你正在寻找像connected-component labeling algorithm这样的东西。它旨在用唯一的标记值标记每个连接的区域)
答案 1 :(得分:1)
您可以先找到具有边界路径的零点:
在边界中取任意0个单元格,将其标记为-1,递归地为其所有相邻单元格执行此操作(邻居的邻居等等都设置为-1)。一旦没有边界单元为零,则将所有零单元转为2.这意味着它们仅被1包围。毕竟将所有-1转为0.这是O(n),其中n是网格中的单元格数。
这是一个(懒惰的)伪代码,假设我们有n_1xn_2网格:
function fill()
{
for int i=1..n_1
{
recursivecolor(i,1);
recursivecolor(i,n_2);
}
for int j=1..n_2
{
recursivecolor(1,j);
recursivecolor(n_1,j);
}
for i=1..n_1
for j=1 .. n_2
if (a[i][j] == 0)
a[i][j] = 2;
for i=1..n_1
for j=1 .. n_2
if (a[i][j] == -1)
a[i][j] = 0;
}
function recursivecolor(i,j)
{
if (a[i][j]!=0) return;
a[i][j] = -1;
if (a[i-1][j] == 0)
{
a[i-1][j] = -1;
recursivecolor(i-1,j);
}
// do this for all neighbours of i,j cell
// it also needs check for boundaries, e.g. i-1 should not be zero ...
}