[Luogu1429]平面最近点对(加强版)

题目大意:
  平面最近点对。

思路:
  分治。
  首先将所有点排序
  每次把当前区间分为两半,递归求解两个区间内部的情况,然后枚举区间两边的点。

 1 #include<cmath>
 2 #include<cstdio>
 3 #include<cctype>
 4 #include<algorithm>
 5 inline int getint() {
 6     register char ch;
 7     while(!isdigit(ch=getchar()));
 8     register int x=ch^'0';
 9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
10     return x;
11 }
12 typedef std::pair<double,double> Point;
13 const int N=200000;
14 Point p[N];
15 int num[N];
16 double ans=1e10;
17 inline double sqr(const double &x) {
18     return x*x;
19 }
20 inline double dis(const Point &a,const Point &b) {
21     return sqrt(sqr(std::abs(a.first-b.first))+sqr(std::abs(a.second-b.second)));
22 }
23 void solve(const int &l,const int &r) {
24     if(l==r) return;
25     const int mid=(l+r)/2;
26     solve(l,mid);1`6
27     solve(mid+1,r);
28     num[0]=0;
29     for(register int i=mid+1;i<=r;i++) {
30         if(p[i].first-p[mid].first<ans) {
31             num[++num[0]]=i;
32         }
33     }
34     for(register int i=l;i<=mid;i++) {
35         if(p[mid].first-p[i].first<ans) {
36             for(register int j=1;j<=num[0];j++) {
37                 ans=std::min(ans,dis(p[i],p[num[j]]));
38             }
39         }
40     }
41 }
42 int main() {
43     const int n=getint();
44     for(register int i=0;i<n;i++) {
45         scanf("%lf%lf",&p[i].first,&p[i].second);
46     }
47     std::sort(&p[0],&p[n]);
48     solve(0,n-1);
49     printf("%.4f\n",ans);
50     return 0;
51 }

 

posted @ 2018-01-09 13:14  skylee03  阅读(119)  评论(0编辑  收藏  举报