了解扫描线最近对的具体实现

时间:2014-12-28 07:43:23

标签: c++ algorithm set points closest-points

首先,我正在阅读扫描线算法,以便在topcoder的O(N lgN)时间内找到最接近的点对。我主要理解这个算法,但是当我看到提供的here实现(在下面复制并使其更具可读性)时,我注意到了一些显着的差异。

#define x first
#define y second
typedef pair<long long, long long> pll;
   ...
set <pll> boundingBox;
boundingBox.insert(points[0]); //Points have been already sorted by x-coordinate
for (int i = 1; i < numPoints; i++)
{
    while ((left < i) && (points[i].x - points[left].x > shortestDistSoFar))
    {
        boundingBox.erase(points[left]);
        left++;
    }

    for (auto it = boundingBox.lower_bound(pll(points[i].y - shortestDistSoFar, points[i].x - shortestDistSoFar)); it != boundingBox.end() && it->y <= points[i].y + shortestDistSoFar; it++)
    {
        if (dist(*it, points[i]) < shortestDistSoFar)
        {
            shortestDistSoFar = dist(*it, points[i]);
            best1 = *it;
            best2 = points[i];
        }
    }
    boundingBox.insert(points[i]);
}

首先,在上面的实现代码片段中,保存点并表示边界矩形的std :: set不按y坐标(而不是x坐标)排序,这与几乎所有其他源所说的相反: The set is ordered by y coordinate. (Topcoder)

接下来,即使该集合未按y坐标排序,当迭代器用于consider points in the active set ... whose y coordinates are in the range yN − h to yN + h时,它也被视为pll(points[i].y - shortestDistSoFar, points[i].x - shortestDistSoFar)的下限。为什么y先来?我认为正确的顺序是pll(points[i].x, points[i].y - shortestDistSoFar),但将其更改为会破坏算法。

有人可以帮助解决这些看似不一致的事情吗?

1 个答案:

答案 0 :(得分:1)

在原始代码中,y坐标是一对的第一个元素。这就是为什么一组中的点被正确排序的原因。