模板题,给出一些点,求两点间最近和最远距离。
代码:
#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);
}
}