P1452 [USACO03FALL]Beauty Contest G
P1452 [USACO03FALL]Beauty Contest G
链接
P1452 [USACO03FALL]Beauty Contest G
题解
旋转卡壳的板子题。就是求凸包直径嘛。。
就是凸包上的一些单调性吧,我们按逆时针遍历凸包的边,边对应的最远点也是逆时针的。
然后就是\(O(nlogn+n)\) 的了。
\(Code\)
#include <bits/stdc++.h>
#define LL long long
#define LD double
using namespace std;
const int N=1e5+10;
const LD eps=1e-6;
int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void print(LL x){
if(x>9) print(x/10);
putchar(x%10+'0');
}
struct P{
LL x,y;
LL len(){return x*x+y*y;}
P(LL xx=0,LL yy=0){x=xx;y=yy;}
};
P operator - (P x,P y){return P(x.x-y.x,x.y-y.y);}
P operator + (P x,P y){return P(x.x+y.x,x.y+y.y);}
LL operator * (P x,P y){return x.x*y.y-x.y*y.x;}
LL dis(P x,P y){return (x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y);}
bool cmp1(P x,P y){return x.y<y.y||(x.y==y.y&&x.x<y.x);}
bool cmp2(P x,P y){return x*y>0||(x*y==0&&x.len()<y.len());}
void Convex(P *A,int &n){
sort(A+1,A+1+n,cmp1);
P O=A[1];
for(int i=2;i<=n;++i){
A[i]=A[i]-A[1];
}
sort(A+2,A+1+n,cmp2);
int tp=1;
for(int i=2;i<=n;++i){
while(tp>=3&&((A[i]-A[tp-1])*(A[tp]-A[tp-1])>=0)) --tp;
A[++tp]=A[i];
}
n=tp;
for(int i=2;i<=n;++i) A[i]=A[i]+O;
return;
}
LL getMaxDis(P *A,int &n){
A[n+1]=A[1];
if(n==2)return dis(A[1],A[2]);
int j=3;
LL res=0;
for(int i=1;i<=n;++i){
while(abs((A[i+1]-A[i])*(A[j]-A[i]))<abs((A[i+1]-A[i])*(A[j+1]-A[i]))){
++j;if(j>n)j%=n;
}
res=max(res,max(dis(A[i],A[j]),dis(A[i+1],A[j])));
}
return res;
}
int n;
P C[N];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i){
scanf("%lld%lld",&C[i].x,&C[i].y);
}
Convex(C,n);
LL ans=getMaxDis(C,n);
printf("%lld\n",ans);
return 0;
}