最近对问题
1.问题:
给定平面上n个点,找出其中的一对点的距离,使得在这n个点的所有点对中,该距离为所有点对中最小的。
2.分析
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s9UuEUkL-1623763947899)(https://z3.ax1x.com/2021/06/15/2qUWHf.png)]
当前的d1,d2都是两边各自的点的最近距离,但是没有考虑到两边的点相互配对的情况,即是点对一个在左边区域,一个在右边区域。可以用上面找到的d来限制配对.即是明显超过d的两点不需要配对,如下
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xGHgOlvU-1623763947901)(https://z3.ax1x.com/2021/06/15/2qaU2j.png)]
以中间线为中心,dmin 为半径划分一个长带,最小点对还有可能存在于s1和s2的交界处,,p点和q点分别位于S1和S1的虚线范围内,只有在这个范围内,p点和q点之间的距离才会小于dmin。
伪代码
double closeset(int low, int high)
{
if (low == high)
return MAX;
if (low + 1 == high)
return dist(p[low], p[high]);
int mid = (low + high)>>1;
(low+high)/2
double ans = min(closeset(low, mid), closeset(mid+1, high));
int i, j, c = 0;
for (i = low; i <= high; i++)
{
if (p[mid].x - ans <= p[i].x && p[i].x <= p[mid].x + ans)
a[c++] = i;
}
sort(a, a + c, cmpy);
for(i = 0; i < c; i++)
{
int k = i+7 > c ? c : i+7;
for (j = i+1; j < k; j++)
{
if (p[a[j]].y - p[a[i]].y > ans)
break;
ans = min(dist(p[a[i]], p[a[j]]), ans);
}
}
return ans;
}
源码
https://github.com/Ace16602/zuijindui