PTA9 哪两个点之间的距离最近[增强版]

设P={(x1​,y1​),(x2​,y2​),⋯,(xn​,yn​)}是平面上散列的n个点的集合。请编写程序找出集合中距离最近的点对。严格地说,相同距离的最近点对可能不止一对,为了简单期间只找出第一对最近点对即可。题目保证输入的所有数据均按照横坐标值进行升序排列。

输入格式:

输入第一行给出一个正整数n,表示平面上点的数数量。随后n行,每行给出一个实数对,每个实数对表示一个点的坐标值,其中第1数表示横坐标,第2数表示纵坐标。

输出格式:

输出最近点对中两个点的坐标和它们之间的距离。如果 x1+y1<=x2+y2则按
  (x1,y1),(x2,y2),miniDist=Distance
输出结果,否则按
  (x2,y2),(x1,y1),miniDist=Distance
输出结果。
  其中x1,y1,x2,y2是保留两位小数的实数,Distance是保留3位小数的实数

输入样例:

5
-1.00 2.00
0.00 2.00
0.50 0.60
1.00 1.00
2.00 0.00

输出样例:

(0.50,0.60),(1.00,1.00),miniDist=0.640

 

#include<bits/stdc++.h>
#define db double
#define rep(x,y,z) for(int x=y;x<=z;++x)
using namespace std;
const int N=1e6+10;
const db qwq=1e18;
int n,s1,s2,t[N];
db sur=1e18;
struct point{db x,y;}d[N];

inline db dis(int x,int y)
{
    db dx=d[x].x-d[y].x,dy=d[x].y-d[y].y;
    return sqrt(dx*dx+dy*dy);
}

inline db run(int l,int r)
{
    if(l==r) return qwq;
    int mid=(l+r)>>1;
    db d=min(run(l,mid),run(mid+1,r));
    int temp=0;
    rep(i,l,r)
        if(dis(i,mid)<d) t[++temp]=i;
    rep(i,1,temp) rep(j,i+1,temp)
    {
        db dist=dis(t[i],t[j]);
        d=min(d,dist);
        if(dist<sur)
        {
            sur=dist;
            s1=t[i];s2=t[j];
        }
    }
    return d;
}

int main()
{
    scanf("%d",&n);

    rep(i,1,n) 
    scanf("%lf%lf",&d[i].x,&d[i].y);
    // sort(d+1,d+n+1,[&](point x,point y){return x.x<y.x;});
    db ans=run(1,n);
    if(d[s1].x+d[s1].y>d[s2].x+d[s2].y) swap(s1,s2);
    printf("(%.2f,%.2f),(%.2f,%.2f),miniDist=%.3f",d[s1].x,d[s1].y,d[s2].x,d[s2].y,ans);
    return 0;
}

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值