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

本文介绍了一种解决平面最近点对问题的分治算法实现。通过将点集按x坐标排序并递归地将问题分解为子问题来寻找最近的点对,最后检查跨越中线的点对以确保找到全局最小距离。

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

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

 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 }

 

转载于:https://www.cnblogs.com/skylee03/p/8250947.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值