Beauty Contest POJ - 2187(旋转卡壳求凸包的直径)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/leekerian/article/details/89503480
#include <iostream>
#include <cmath>
#include <cstdio>
#include <algorithm>

using namespace std;

const int maxn=66666;
const double eps=1e-8;

int sgn(double x)
{
    if(fabs(x)<eps)
        return 0;
    if(x<0)
        return -1;
    else
        return 1;
}

struct Point
{
    double x,y;
    Point(){}
    Point(double _x,double _y)
    {
        x=_x;
        y=_y;
    }
    Point operator -(const Point &b)const
    {
        return Point(x-b.x,y-b.y);
    }
    double operator ^(const Point &b)const
    {
        return x*b.y-y*b.x;
    }
    int operator *(const Point &b)const
    {
        return x*b.x+y*b.y;
    }
};

Point p[maxn];
Point p1[maxn];
double dist(Point a,Point b)
{
    return sqrt((a-b)*(a-b));
}

bool cmp(Point a,Point b)
{
    int ans=sgn((a-p[0])^(b-p[0]));
    if(ans==1)
        return true;
    else if(ans==0)
        return dist(a,p[0])<dist(b,p[0]);
    else
        return false;
}

int Stack[maxn];
int top=0;
int n;


void graham()
{
    for(int i=0;i<n;i++)
    {
        if(p[i].y<p[0].y||(p[i].y==p[0].y&&p[i].x<p[0].x))
            swap(p[i],p[0]);
    }
    sort(p+1,p+n,cmp);
    if(n==1)
    {
        Stack[0]=0;
        top=1;
    }
    else if(n==2)
    {
        Stack[0]=0;
        Stack[1]=1;
        top=2;
    }
    else
    {
        Stack[0]=0;
        Stack[1]=1;
        top=2;
        for(int i=2;i<n;i++)
        {
            while(top>0&&((p[Stack[top-1]]-p[Stack[top-2]])^(p[i]-p[Stack[top-2]]))<=0)
            {
                top--;
            }

            Stack[top++]=i;
        }
    }
}

int dist2(Point a,Point b)
{
    return (a-b)*(a-b);
}

int rotating_calipers(Point p1[],int n)
{
    int cur=1;
    int ans=0;
    for(int i=0;i<n;i++)
    {
        Point p;
        p=(p1[i]-p1[(i+1)%n]);
        while(sgn(p^(p1[(cur+1)%n]-p1[cur]))<0)
            cur=(cur+1)%n;
       ans = max(ans,max(dist2(p1[i],p1[cur]),dist2(p1[(i+1)%n],p1[cur])));
    }
    return ans;
}

int main()
{
    cin>>n;
    for(int i=0;i<n;i++)
    {
        scanf("%lf %lf",&p[i].x,&p[i].y);
    }
    graham();
    for(int i=0;i<top;i++)
    {
        p1[i]=p[Stack[i]];
    }
    int ans=rotating_calipers(p1,top);
    printf("%d\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/leekerian/article/details/89503480