这是来自 CLRS 的一个问题。圆盘由一个圆加上它的内部组成,并由它的中心点和半径表示。如果两个磁盘有任何共同点,则它们相交。给出一个 O(n lg n) 时间的算法来确定一组 n 中的任意两个磁盘是否相交。
这不是我的家庭作业。我认为我们可以将每个圆的水平直径作为代表线段。如果两个订单是连续的,那么我们检查两个中心之间的距离长度。如果它小于或等于圆的半径之和,则它们相交。
如果我正确,请告诉我。
这是来自 CLRS 的一个问题。圆盘由一个圆加上它的内部组成,并由它的中心点和半径表示。如果两个磁盘有任何共同点,则它们相交。给出一个 O(n lg n) 时间的算法来确定一组 n 中的任意两个磁盘是否相交。
这不是我的家庭作业。我认为我们可以将每个圆的水平直径作为代表线段。如果两个订单是连续的,那么我们检查两个中心之间的距离长度。如果它小于或等于圆的半径之和,则它们相交。
如果我正确,请告诉我。
为磁盘中心构建 Voronoi 图。这是一个 O(n log n) 的工作。
现在为图表的每条边取相应的一对中心并检查它们的圆盘是否相交。
(p, r)
,使用 kd 树找到S
中心比2r
from更近的圆的集合p
。S
接触当前圆圈。我认为这个算法的平均成本是 O(NlogN)。
逻辑是我们在集合上循环O(N)
,并且对于每个元素都得到一个靠近 的元素子集O(NlogN)
,因此,先验的复杂度是O(N^2 logN)
。但是我们还必须考虑两个随机圆相隔小于2r
且不接触的概率小于3/4
(如果它们接触,我们可以短路算法)。
这意味着 的平均大小在S
概率上被限制为一个很小的值。
解决问题的另一种方法:
在 scala 中实现的相同算法:https ://github.com/salva/simplering/blob/master/touching/src/main/scala/org/vesbot/simplering/touching/Circle.scala