【问题标题】:N points are given in Euclidean plane. For each point, find the smallest distance between itself and the other pointsN 个点在欧几里得平面上给出。对于每个点,找到它自己和其他点之间的最小距离
【发布时间】:2019-08-20 14:55:51
【问题描述】:

问题很简单:n 点在欧几里得平面上由它们的坐标给出。对于每个点,您应该使用欧几里得距离找到其自身与任何其他点之间的最小距离。这个最小距离称为该点的半径。对于每一点,我们应该返回两件事:

  1. 半径(r)。

  2. 欧几里得距离小于或等于2*r的点数(不包括自身)。

输入限制:

1 <= number of coordinates <= 30000
0 <= x,y <= 10000

好吧,我已经在o(n^2) 中完成了这项工作。谁有更好的解决方案??

例子:

1. n=3
(0,0)
(0,0)
(3,4)

output-
(0.00 1)
(0.00 1)
(5.00 2)

2. n=5
(5,3)
(7,8)
(0,9)
(3,1)
(4,4)

output-
(1.41 2)
(5.00 4)
(6.40 4)
(2.83 2)
(1.41 1)

【问题讨论】:

  • 每个解决方案都必须计算每对点之间的距离吗?有几对?
  • @DavidBrowne-Microsoft 是的,每个解决方案都必须计算每对点之间的距离,对于每种情况,我们都会得到 n 个点。
  • 请添加语言标签。
  • 好吧,既然要计算 n(n-1)/2 个距离,你就有答案了。

标签: math coordinates


【解决方案1】:

首先,认识到距离是对称的。 ij 的距离与ji 的距离相同。总共有n*(n-1)/2 距离要计算。

如果您使用以下循环预先计算它们,那么任何进一步的处理,例如扫描最近的,都会非常快。

// n = number of points
distances=new float[n*(n-1)/2];
int index = 0;
for (int i = 0; i<n-1; i++)
{
    for (int j = i+1; j<n; j++)
    {
        // This is by far the most expensive operation to make:
        distances[index++]=Vector2.Distance(Points[i], Points[j]);                    
    }
}

而不是得到两点之间的距离ij 很快。

class PointCloud
{

    int n;
    float[] distances;

    float GetDistance(int i, int j)
    {
        if(i==j) return 0;
        if(i>j) return GetDistance(j ,i);
        int index = -i*(i-2*n+1)/2+(j-i)-1;
        return distances[index];
    }
}

计算index = -i*(i-2*n+1)/2+(j-i)-1解释如下。我们只存储矩阵的上三角值和距离。每行i 都有row=n-i-1 值,第一个值(最靠近对角线)的索引是start=sum(n-t-1,t=0,i-1) = -i*(i-2*n+1)/2j 列的索引是 index = start + j- i -1,这是 j 和对角线旁边的列位置之间的差异。

例如,n=4 只需要存储 6 个值。每对的距离数组的索引计算如下:

  j=0      j=3
| *  0  1  2 | i=0
| 0  *  3  4 |
| 1  3  *  5 |
| 2  4  5  * | i=3

所以要得到i=1j=3之间的距离,上面有index=4distances[index]是需要的值。注意-i*(i-2*n+1)/2+(j-i)-1 = -1*(1-2*4+1)/2+(3-1)-1 = 4

- 参考帖子:https://stackoverflow.com/a/9040526/380384 用于压缩形式的对称矩阵,但存储上三角值对角线的矩阵。所以,相似但不准确。

与对所有对的双嵌套循环的幼稚方法相比,上述方法基本上将处理量减少了一半。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-11
    • 2019-05-07
    • 2011-01-29
    • 2021-01-30
    • 2019-07-10
    • 1970-01-01
    • 2023-03-25
    • 2021-05-14
    相关资源
    最近更新 更多