模板题,给出一些点,求两点间最近和最远距离。

代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <cmath>
#define N 50010
#define eps 1e-6
using namespace std;
int dcmp(double x){if (fabs(x)<eps)return 0;else return x<0?-1:1;}

struct Point
{
    double x,y;
    bool operator < (const Point &a)const
    {return dcmp(x-a.x)<0 || (dcmp(x-a.x)==0 && dcmp(y-a.y)<0);}
    Point(double x=0,double y=0):x(x),y(y){ }
    void read(){scanf("%lf%lf",&x,&y);}
}a[N],b[N];
typedef Point Vector;
Vector operator - (Vector a,Vector b){return Vector(a.x-b.x,a.y-b.y);}
double Dot(Vector a,Vector b){return a.x*b.x+a.y*b.y;}  //点积
double Length(Vector a){return sqrt(Dot(a,a));}
double Cross(Vector a,Vector b){return a.x*b.y-a.y*b.x;} //叉积

Point tp[N];
double ans;

bool cmpy(Point a,Point b){
 return a.y<b.y;
}
double solve(int l,int r)
{
    double d=1e10;
    if(l>=r) return d;
    if (l==r-1) return d=min(d,Length(a[l]-a[r]));
    int mid=l+r >> 1;
    double midx=a[mid].x;
    double d1=solve(l,mid);
    double d2=solve(mid+1,r);
    d=min(d1,d2);
    int cnt=0;
    for(int i=l;i<=r;i++)
    if(dcmp(fabs(a[i].x-midx)-d)<=0)tp[cnt++]=a[i];
    sort(tp,tp+cnt,cmpy);
    for(int i=0;i<cnt;i++)
        for(int j=i+1;j<cnt && dcmp(tp[j].y-tp[i].y-d)<0;j++)
        d=min(d,Length(tp[i]-tp[j]));
    return d;
}

int ConvexHull(Point *p, int n, Point* ch) {
    sort(p, p+n);      //先比较x坐标,再比较y坐标
    int m = 0;
    for(int i = 0; i < n; i++) {
        while(m > 1 && Cross(ch[m-1] - ch[m-2], p[i]-ch[m-2]) <= 0) m--;
        ch[m++] = p[i];
    }
    int k = m;
    for(int i = n-2; i >= 0; i--) {
        while(m > k && Cross(ch[m-1] - ch[m-2], p[i]-ch[m-2]) <= 0) m--;
        ch[m++] = p[i];
    }
    if(n > 1) m--;
    return m;
}

//最远点对,先求凸包,p是凸包
double convex_diameter(Point *p,int n,int &x,int &y)
{
    double ans=0.0;
    if (n==1){ x=y=0; return ans;}
    #define nx(i) ((i+1)%n)
    for (int i=0,j=1;i<n;i++)
    {
        while (dcmp(Cross(p[nx(i)]-p[i],p[j]-p[i])-Cross(p[nx(i)]-p[i],p[nx(j)]-p[i]))<0) j=nx(j);
        double d=Length(p[i]-p[j]);
        if (d>ans){ ans=d;x=i;y=j;}
        d=Length(p[nx(i)]-p[nx(j)]);
        if (d>ans){ans=d;x=i;y=j;}
    }
    return ans;
}
int main()
{
    int n;int T=0;
    while(scanf("%d",&n)&&n!=0)
    {
        for(int i=0;i<n;i++)a[i].read();
        sort(a,a+n);
        ans=solve(0,n-1);
        printf("Case %d:\n",++T);
        printf("Distance of the nearest couple is %.3f\n",ans);
        int m=ConvexHull(a,n,b);int x,y;
        ans=convex_diameter(b,m,x,y);
        printf("Distance of the most distant couple is %.3f\n\n",ans);
    }
}