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;
}
posted @ 2020-10-23 09:12  Iscream-2001  阅读(128)  评论(0编辑  收藏  举报
/* */ /* */