Algorithm 如何在二维数组中找到最大圆
给定一个二维Algorithm 如何在二维数组中找到最大圆,algorithm,multidimensional-array,Algorithm,Multidimensional Array,给定一个二维n*n数组,其中每个元素都是+或x,我们如何找到仅由+字符构成的最大圆直径 例如: xxxxx x++++ x+++x x+++x xxxxx 最大直径为2,圆原点为圆心 在所有情况下,圆可能不会在二维阵列中居中 有没有一个简单的算法来解决这个问题?我不是在寻找代码,只是一个算法。 谢谢 将是一个直径为2的圆来回答关于边缘的问题。解决这个问题的方法是将自由单元(+)想象成海洋,将其他单元(x)想象成陆地。该算法在海岸线处启动一个向各个方向流动的水波(直到它击中另一个波浪或陆地)
n*n
数组,其中每个元素都是+
或x
,我们如何找到仅由+
字符构成的最大圆直径
例如:
xxxxx
x++++
x+++x
x+++x
xxxxx
最大直径为2,圆原点为圆心
在所有情况下,圆可能不会在二维阵列中居中
有没有一个简单的算法来解决这个问题?我不是在寻找代码,只是一个算法。
谢谢
将是一个直径为2的圆来回答关于边缘的问题。解决这个问题的方法是将自由单元(
+
)想象成海洋,将其他单元(x
)想象成陆地。该算法在海岸线处启动一个向各个方向流动的水波(直到它击中另一个波浪或陆地)。最后一片被波浪覆盖的海洋是一个半径最大的圆心
这导致了更正式的算法:
count
为空闲单元格的数量(+
的数量)李>
count
为零,则无结果退出coast
,其中包含已占用单元(具有x
的单元)的单元坐标
- 还可以将位于网格外的虚拟单元添加到
,因为它们也表示“陆地”海岸
半径的圆的相对坐标(好像以单元格[0,0]为中心)。对于半径1,这将是:
[ [-1, 0], [0, -1], [1, 0], [0, 1] ]
中心
=在海岸
中引用的单元格:
- 获取圆上具有此
和中心
的自由单元格,并针对每个:半径
- 将其标记为已占用,并减少计数
- 如果
为零,则我们有一个解决方案:此单元格是要绘制的圆的中心,其半径应为count
。退出radius-1
- 如果此圆上没有空闲的单元格,请将
从中心
中移除(以避免将来进行不必要的检查)海岸
半径
并从步骤5开始重复
当算法退出并得到一个结果(一个中心和一个半径)时,可以直接将给定的网格与实际磁盘重叠
下面是一个JavaScript实现(不使用任何较新的语法,因此应该很容易阅读),您可以在这里运行:
“严格使用”;
函数回路坐标(半径){
var单元格=[];
var r2=(半径+0.41)*(半径+0.41);//常数决定边距
var i=0;
var j=半径;
而(i r2){
j--;
//在这里,递减i不是标准,但需要进行调整
//确实我们覆盖了添加的表面,而不是带有
//半径为一个单位,小于一个单位。
我--;
}
}
返回单元;
}
函数求解(a){
变量i,j,k,l,m,n,count,coast,circle,reduced,radius,b;
函数get(b,i,j){
如果(i<0 | | j<0 | | i>=b.length | | j>=b[i].length)
返回1;
返回b[i][j];
}
//复制输入,计数空闲单元格,并在“coast”中收集其他单元格
计数=0;
海岸=[];
b=[];
对于(i=0;i=0)和&count;k--){
减少=错误;
对于(l=0;(l1
}
}
返回a;
}
函数arrayToText(a){
//将二维数组转换回文本。2个值将转换为“#”
var线,i,j;
行=[];
对于(i=0;i[ [-1, 0], [0, -1], [1, 0], [0, 1] ]