【模拟试题】最远距离点对
Description
给定平面上的n个点,找出它们之间最远的点对。
Input
多组数据,每组第一行n代表点数,接着n行为点的坐标,坐标为整数,不超过10^18范围。n<=30000。
Output
每组一行,最远点对的距离,保留2位小数
Sample Input
4
0 0
1 1
0 1
1 0
Sample Output
1.41
Source
找出凸包,旋转卡壳。
注意方向。。。
CODE
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
struct Point {long long x,y;}p[30005];
inline bool cmp(Point A,Point B){return A.y<B.y||A.y==B.y&&A.x<B.x;}
int S[30005],q[30005];
inline long long read(){
char c;int rec=0,f=1;
while((c=getchar())<'0'||c>'9')if(c=='-')f=-1;
while(c>='0'&&c<='9')rec=rec*10+c-'0',c=getchar();
return rec*f;
}
int n;
inline long long Cross(Point A,Point B,Point X){
return (A.x-X.x)*(B.y-X.y)-(B.x-X.x)*(A.y-X.y);
}
inline long long Cal(Point A,Point B){
return (A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y);
}
void Scan(){
int i,j,top=2;
q[1]=1;q[2]=2;
for(i=3;i<=n;i++){
while(top>1&&Cross(p[q[top]],p[i],p[q[top-1]])<=0)top--;
q[++top]=i;
}
for(i=1;i<=top;i++)S[i]=q[i];S[0]=top;
q[1]=n;q[2]=n-1;top=2;
for(i=n-2;i>=1;i--){
while(top>1&&Cross(p[q[top]],p[i],p[q[top-1]])<=0)top--;
q[++top]=i;
}i=1;
if(q[1]==S[S[0]])i=2;
for(;i<=top;i++)S[++S[0]]=q[i];
return ;
}
void Farest(){
int i,j=1;
long long ans=0;
S[n+1]=S[1];
for(i=1;i<=S[0];i++){
while(Cross(p[S[i+1]],p[S[j+1]],p[S[i]])>Cross(p[S[i+1]],p[S[j]],p[S[i]]))j=(j+1)%S[0];
ans=max(ans,max(Cal(p[S[i+1]],p[S[j+1]]),Cal(p[S[i]],p[S[j]])));
}
printf("%.2lf",sqrt(double(ans)));
return ;
}
int main(){
n=read();
int i,x,y;
for(i=1;i<=n;i++){p[i].x=read();p[i].y=read();}
sort(p+1,p+1+n,cmp);
Scan();
Farest();
return 0;
}