绍兴网站建设团队,门户网站建设和运行保证的磋商文件,网站死链接检查,北京外包公司名单正题 
题目链接:https://www.luogu.com.cn/problem/P1429 题目大意 
平面上nnn个点#xff0c;求最近点对 解题思路 
考虑分治求最近点对#xff0c;首先将平行于yyy轴将平面穿过xxx左边的中位数分割成两半#xff0c;现在最近点对有三种可能#xff0c; 
在分割线左边在分…正题 
题目链接:https://www.luogu.com.cn/problem/P1429 题目大意 
平面上nnn个点求最近点对 解题思路 
考虑分治求最近点对首先将平行于yyy轴将平面穿过xxx左边的中位数分割成两半现在最近点对有三种可能 
在分割线左边在分割线右边穿过分割线 
我们知道1和2可以用分治到两边计算考虑如何求情况3。暴力枚举对数肯定会TLETLETLE考虑优化假设我们已经知道1和2的最小解d1,d2d1,d2d1,d2了我们有dmin{d1,d2}dmin\{d1,d2\}dmin{d1,d2}那么我们可以以分割线为对称轴做一个2d∗d2d*d2d∗d的矩形最近点对的两个点一定在这个矩形内。 
这样计算为什么可以优化算法因为矩阵内的点数是常数级别的首先我们可以由分割线分割成两个小正方形我们知道正方形内的点距离一定不小于ddd那么一个正方形内最多只有常数级别的点数好像是3个的样子 
所以时间复杂度O(nlogn)O(n\log n)O(nlogn) codecodecode 
#includecstdio
#includecstring
#includealgorithm
#includecmath
using namespace std;
const int N2e510;
int n,p[N],c[N];
double x[N],y[N];
bool cmp(int a,int b)
{return (x[a]x[b])?(y[a]y[b]):(x[a]x[b]);}
bool cMp(int a,int b)
{return y[a]y[b];}
double get_dis(int a,int b)
{return sqrt((x[a]-x[b])*(x[a]-x[b])(y[a]-y[b])*(y[a]-y[b]));}
double Solve(int l,int r){double d1e18;if(lr)return d;if(l1r)return get_dis(p[l],p[r]);int mid(lr)1;double d1Solve(l,mid);double d2Solve(mid1,r);dmin(d1,d2);int tot0;for(int il;ir;i)if(fabs(x[p[i]]-x[p[mid]])d)c[tot]p[i];sort(c1,c1tot,cMp);for(int i0;itot;i){for(int ji1;jtot;j){if(y[c[j]]-y[c[i]]d)break;double Dget_dis(c[i],c[j]);dmin(d,D);}}return d;
}
int main()
{scanf(%d,n);for(int i1;in;i){scanf(%lf%lf,x[i],y[i]);p[i]i;}sort(p1,p1n,cmp);printf(%.4lf,Solve(1,n));
}