POJ2187:Beauty Contest——题解

http://poj.org/problem?id=2187

题目大意:给n个点,求点对最大距离的平方。

————————————————————

很容易证明最大距离的点对在最大凸包上。

那么就是旋转卡壳的裸题了。

旋转卡壳要不要写讲解呢……

#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e5+5;
inline int read(){
    int X=0,w=0;char ch=0;
    while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
    while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    return w?-X:X;
}
struct Point{
    int x,y;
    Point(int x0=0,int y0=0){x=x0,y=y0;}
};

int dis(Point a,Point b){//求两点距离平方 
    return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}

typedef Point Vector;
Vector operator +(Point a,Point b){return Vector(a.x+b.x,a.y+b.y);}
Vector operator -(Point a,Point b){return Vector(a.x-b.x,a.y-b.y);}
Vector operator *(Point a,int k){return Vector(a.x*k,a.y*k);}
Vector operator /(Point a,int k){return Vector(a.x/k,a.y/k);}

int Dot(Vector a,Vector b){//求点积 
    return a.x*b.x+a.y*b.y;
}
int Cross(Vector a,Vector b){//求叉积
    return a.x*b.y-b.x*a.y;
}
int Cross(Point sp,Point ep,Point op){//得到sp-op和ep-op的叉积
    return (sp.x-op.x)*(ep.y-op.y)-(ep.x-op.x)*(sp.y-op.y);
}

Point p[N],q[N];
int n,k,m;
inline bool cmp(int u,int v){
    int det=Cross(p[u],p[v],p[1]);
    if(det!=0)return det>0;
    return dis(p[1],p[u])<dis(p[1],p[v]);
}
void graham(){
    int id=1;
    for(int i=2;i<=n;i++)
        if(p[i].x<p[id].x||(p[i].x==p[id].x&&p[i].y<p[id].y))
            id=i;
    if(id!=1)swap(p[1],p[id]);
    
    static int per[N];
    for(int i=1;i<=n;i++)per[i]=i;
    sort(per+2,per+n+1,cmp);
    
    q[++m]=p[1];
    for(int i=2;i<=n;i++){
        int j=per[i];
        while(m>=2&&Cross(p[j],q[m],q[m-1])>=0)m--;
        q[++m]=p[j];
    }
    return;
}
int calliper(){
    if(m==2)return dis(q[1],q[2]);
    q[m+1]=q[1];
    int res=0;
    for(int i=1,j=3;i<=m;i++){
        while(Cross(q[i+1],q[j],q[i])<Cross(q[i+1],q[j+1],q[i])){
            j++;if(j>m)j=1;
        }
        res=max(res,dis(q[i],q[j]));
    }
    return res;
}
int main(){
    n=read();
    for(int i=1;i<=n;i++)p[i].x=read(),p[i].y=read();
    graham();
    printf("%d\n",calliper());
    return 0;
}

 

posted @ 2017-12-23 18:25  luyouqi233  阅读(222)  评论(0编辑  收藏  举报