我有来自二维数组的场,其中1是陆地,0是什么都没有。当两块土地停留在同一面墙上时,被称为邻居。当一块土地没有邻居被称为岛屿时,它有两个或更多的邻居称为大陆。我必须计算场上所有的岛屿和大陆。这就是我找到这些岛屿的方式。
int find_islands(const int array[][8]) { // Find the islands in the field.
int count = 0;
for (int i = 0; i < 8; i++)
{
for (int x = 0; x < 8; x++)
{
if (array[i][x] == 1)
{
if (i == 0)
{
if (x == 0)
{
if (array[i][x + 1] == 0 && array[i + 1][x] == 0)
{
count++;
}
}
else if (x == 7)
{
if (array[i][x - 1] == 0 && array[i + 1][x] == 0)
{
count++;
}
}
else
{
if (array[i][x + 1] == 0 && array[i][x - 1] == 0 && array[i + 1][x] == 0)
{
count++;
}
}
}
else if (i == 7)
{
if (x == 0)
{
if (array[i][x + 1] == 0 && array[i - 1][x] == 0)
{
count++;
}
}
else if (x == 7)
{
if (array[i][x - 1] == 0 && array[i - 1][x] == 0)
{
count++;
}
}
else
{
if (array[i][x + 1] == 0 && array[i][x - 1] == 0 && array[i - 1][x] == 0)
{
count++;
}
}
}
else
{
if (x == 0)
{
if (array[i][x + 1] == 0 && array[i + 1][x] == 0 && array[i - 1][x] == 0)
{
count++;
}
}
else if (x == 7)
{
if (array[i][x - 1] == 0 && array[i + 1][x] == 0 && array[i - 1][x] == 0)
{
count++;
}
}
else
{
if (array[i][x + 1] == 0 && array[i][x - 1] == 0 && array[i + 1][x] == 0 && array[i - 1][x] == 0)
{
count++;
}
}
}
}
}
}
return count;}
这是一个示例数组。
int board[8][8] = {
{0, 1, 0, 0, 1, 1, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},
{1, 1, 0, 0, 1, 0, 0, 0},
{1, 1, 0, 0, 1, 0, 0, 1},
{0, 0, 0, 1, 0, 1, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},
{1, 1, 1, 1, 1, 0, 0, 0},
{1, 0, 0, 1, 1, 0, 1, 0} };
我的问题是我无法想办法找到各大洲。提前谢谢!
答案 0 :(得分:0)
您正在寻找的算法是洪水填充。为简单起见,让我们稍微改变规则并将岛屿视为大陆。想象一下,我们扭转了这种情况,因此现在的碎片是平坦表面上的深孔。你可以做些什么来统计大陆,就是反复挑选一个你以前从未见过的洞,并将一堆水倒入其中。
这将淹没与之相关的所有内容。当你看到一个已经被洪水淹没的地方时,你知道它是你以前计算过的一个大陆的一部分,你不应该再计算它。
如何使用代码执行此操作?创建一个2D布尔数组来存储一个地方是否被洪水淹没。我们可以称之为visited
。现在,我们编写一个函数来模拟洪水过程,它将一个正方形的坐标作为开始洪水填充的位置。
我们可以使用std::queue
来存储我们接下来要处理的位置。每次我们处理一个正方形时,我们将其标记为已访问,然后查看其相邻的正方形。如果相邻的广场是一片土地而我们尚未访问它,我们会将其添加到队列中。
我们现在可以迭代所有的正方形,对于我们看到的尚未访问过的每个正方形,我们在其上调用我们的洪水填充功能,这将泛滥该大陆并标记所有属于它的土地。然后我们可以通过一个计数器来计算各大洲的数量,以便跟踪我们看到未访问的土地的次数并开始填充洪水。
现在我们知道包括1号大陆在内的大陆总量,我们可以简单地减去岛屿的数量,以获得大于单块土地的大陆数量。
我将把实际的实施作为练习留给你。