最远点对
【题目描述】:
给定平面上N个点的坐标,找出距离最远的两个点。
【输入描述】:
第一行一个N,表示平面上的点数。
以下N行,每行一个x和y,表示一个点的横坐标和纵坐标。
【输出描述】:
仅输出最远点对的距离,精确到小数点后两位。
【样例输入】:
8
2720 -443
46 -2422
-2077 -1346
4520 -4963
-1791 1547
-1262 4025
-2997 913
-1667 -2499
【样例输出】:
10687.17
【时间限制、数据范围及描述】:
时间:1s 空间:128M
N<=100,000; -10000<=x,y<=10000
其实这题只需在凸包的基础上加一个搜索就可以了。我们将这些点的凸包坐标找出来,然后在这些坐标中搜索一对最远的点对即可。另:搜索的过程中可以用旋转卡壳的算法进行优化,但这里我就直接暴力求解。
AC代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
ll ox,oy,maxn;
double ansn;
struct node{
ll x,y;
node(){x=0;y=0;}
node(int a,int b){x=a;y=b;}
node(const node &p1){x=p1.x;y=p1.y;}
node operator = (const node &a){
x=a.x;y=a.y;
return *this;
}
};
ll operator *(const node & a,const node & b){
ll xx1=(a.x-ox)*(b.y-oy),xx2=(a.y-oy)*(b.x-ox);
return xx1-xx2;
}
ll mx(ll x,ll y){
return x>y?x:y;
}
bool operator <(const node &a,const node &b){
ll x;
x=a*b;
if(x>0)return 1;
if(x==0){
if((a.x-ox)*(a.x-ox)+(a.y-oy)*(a.y-oy)<(b.x-ox)*(b.x-ox)+(b.y-oy)*(b.y-oy))return 1;
}
return 0;
}
bool comp(const node &a,const node &b){
if((a.x-ox)*(a.x-ox)+(a.y-oy)*(a.y-oy)<(b.x-ox)*(b.x-ox)+(b.y-oy)*(b.y-oy))return 1;
return 0;
}
ll dis(const node &a,const node &b){
return ((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
node s0[100005];
int n,v,k=1;
ll miny=2147483647,minx=-2147483647;
ll ans[100005];
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%lld%lld",&s0[i].x,&s0[i].y);
}
for(int i=0;i<n;i++){
if(miny>s0[i].y){
miny=s0[i].y;
minx=s0[i].x;
v=i;
}
if(miny==s0[i].y){
if(minx>s0[i].x){
minx=s0[i].x;
v=i;
}
}
}
ox=s0[v].x;oy=s0[v].y;
ll temp,xx;
temp=s0[0].x;s0[0].x=s0[v].x;s0[v].x=temp;
temp=s0[0].y;s0[0].y=s0[v].y;s0[v].y=temp;
sort(s0+1,s0+n);
ans[0]=0;ans[1]=1;
for(int i=2;i<n;i++){
ox=s0[ans[k-1]].x;oy=s0[ans[k-1]].y;
xx=(s0[ans[k]]*s0[i]);
if(xx>0){
k++;
ans[k]=i;
}
if(xx==0){
if(comp(s0[i],s0[ans[k-1]]));
ans[k]=i;
}
if(xx<0){
if(k>2){
k--;
i--;
}
else
ans[k]=i;
}
}
for(int i=0;i<=k;i++){
for(int j=0;j<=k;j++){
maxn=mx(maxn,dis(s0[ans[i]],s0[ans[j]]));
}
}
ansn=(double)(sqrt(maxn*1.0));
printf("%.2lf",ansn);
return 0;
}
AC截图: