平面最近点对题解

方法一

我们充分发扬人类的智慧。
xy 分别排序然后取 100 个,进行判断。

方法二

考虑分治将 (1,10) 分成 (1,5),(6,10) 两个问题,再不断分治。
现在我们知道了子问题的答案,考虑合并,首先这个肯定是要横跨两边的,因为不横跨的已经算过了,那么打中间的距离大于现在答案的直接 out ,不可能成为答案。
然后按 y 轴排序,进行枚举点,这个时候如果两个 y 的距离大于答案,直接 break 后面的 y 只会越来越大。
核心代码:

double dfs(int l,int r)
{
	int mid;
	double ans;
	if(l==r) return INF;
	mid=(l+r)/2;
	ans=min(dfs(l,mid),dfs(mid+1,r));
	int k=0;
	for(int i=l;i<=r;++i)
	if(abs(a[mid].x-a[i].x)<=ans) p[++k]=a[i];//可能成为答案的点集 
	sort(p+1,p+1+k,cmp2);
	for(int i=1;i<=k;++i)
	for(int j=i+1;j<=k;++j)
	if(p[j].y-p[i].y<ans) ans=min(ans,sqrt((p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y)));
	else break;//不可能成为答案,后面的也不可能 
	return ans;
}