首先,我正在阅读扫描线算法,以便在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)
,但将其更改为会破坏算法。
有人可以帮助解决这些看似不一致的事情吗?
答案 0 :(得分:1)
在原始代码中,y坐标是一对的第一个元素。这就是为什么一组中的点被正确排序的原因。