题解 P1429 【平面最近点对(加强版)】
此处使用了置顶题解的方法,建议搭配食用。
就是先随机旋转,然后根据横坐标排一遍序,枚举后五个点。
复杂度
#include<bits/stdc++.h>
#define re register
using namespace std;
typedef long long ll;
ll n;
double ans=0x7f7f7f7f7f7f;
struct node {
double x,y;
}p[200010];
inline bool cmp(node a,node b){return a.x<b.x;}
inline double dis(node a,node b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
inline int read(){
ll ans=0;bool f=0;char ch=getchar();
for(;!isdigit(ch);ch=getchar())f^=(ch=='-');
for(;isdigit(ch);ch=getchar())ans=(ans<<3)+(ans<<1)+(ch^48);
return f? -ans: ans;
}
int main(){
n=read();
for(re int i=1;i<=n;i++){
double xx,yy;
scanf("%lf%lf",&p[i].x,&p[i].y);
xx=p[i].x*cos(422)-p[i].y*sin(422);//旋转公式
yy=p[i].x*sin(422)+p[i].y*cos(422);//转两次
p[i].x=xx,p[i].y=yy;
}
sort(p+1,p+n+1,cmp);
for(re int i=1;i<=n;i++){
ans=(ans>dis(p[i+1],p[i]))? dis(p[i+1],p[i]): ans;//枚举可行的点
ans=(ans>dis(p[i+2],p[i]))? dis(p[i+2],p[i]): ans;
ans=(ans>dis(p[i+3],p[i]))? dis(p[i+3],p[i]): ans;
ans=(ans>dis(p[i+4],p[i]))? dis(p[i+4],p[i]): ans;
ans=(ans>dis(p[i+5],p[i]))? dis(p[i+5],p[i]): ans;
}
printf("%.4lf\n",ans);
return 0;
}