[日常摸鱼]POJ2187 BeautyContest-旋转卡壳

原来这个念 旋转卡qia壳ke…

题意:求平面内给定点集里的最远点对,$n \leq 5e4$

 


 

 

做法就是旋转卡壳啦,话说这题数据范围应该可以再大挺多的。

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=50005;
struct Point
{
    double x,y;
    Point(double x=0,double y=0):x(x),y(y){}
}p[N];
inline Point operator -(Point a,Point b)
{
    return Point(a.x-b.x,a.y-b.y);
}
inline double cross(Point a,Point b)
{
    return a.x*b.y-a.y*b.x;
}
inline double sqr2(double x){return x*x;}
inline double dist(Point a,Point b)
{
    return sqrt(sqr2(a.x-b.x)+sqr2(a.y-b.y));
}
inline bool cmp(Point a,Point b)
{
    if(a.x==b.x)return a.y<b.y;
    return a.x<b.x;
}
inline int convexHull(Point *s,int n)
{
    sort(p+1,p+n+1,cmp);
    int t=0,k;
    for(register int i=1;i<=n;i++)
    {
        while(t>1&&cross(s[t]-s[t-1],p[i]-s[t-1])<=0)t--;
        s[++t]=p[i];
    }k=t;
    for(register int i=n-1;i>=1;i--)
    {
        while(t>k&&cross(s[t]-s[t-1],p[i]-s[t-1])<=0)t--;
        s[++t]=p[i];
    }
    if(n>1)t--;
    return t;
}
inline double rotatingCalipers(Point *s,int t)
{
    int now=2;double ans=0;
    s[t+1]=s[1];
    for(register int i=1;i<=t;i++)
    {
        while(cross(s[i+1]-s[i],s[now]-s[i])<cross(s[i+1]-s[i],s[now+1]-s[i]))
            now=now%t+1;
        ans=max(ans,dist(s[i],s[now]));
    }
    return ans;
}
int n,t;
int main()
{
    Point s[N];scanf("%d",&n);
    for(register int i=1;i<=n;i++)scanf("%lf%lf",&p[i].x,&p[i].y);
    t=convexHull(s,n);printf("%.0lf",sqr2(rotatingCalipers(s,t)));
    return 0;
}

 

posted @ 2018-01-18 19:46  yoshinow2001  阅读(146)  评论(0编辑  收藏  举报