POJ 2187 Beauty Contest

题目大意:n个点求凸包,然后求凸包上距离最远的两点。

求凸包然后枚举。恩...旋转卡壳不会。

 

View Code
#include<cstdio>

#include<cstdlib>

#include<cstring>

#include<iostream>

#include<algorithm>

using namespace std;

#define MaxN 50010

struct point

{

    int x,y;

    }p[MaxN];

int n;

int s[MaxN],top;

int a[MaxN],cnt;

bool v[MaxN];

int cross(int i,int j,int k)

{

    int x1=p[j].x-p[i].x,

          y1=p[j].y-p[i].y,

          x2=p[k].x-p[i].x,

          y2=p[k].y-p[i].y;

    return x1*y2-x2*y1;

    }

void graham()

{

    top=2;

    s[1]=1;s[2]=2;

    for (int i=3;i<=n;i++)

    {

        while (top>1 && cross(s[top-1],s[top],i)<0) top--;

        s[++top]=i;

        }

    for (int i=1;i<=top;i++)

        a[++cnt]=s[i],v[s[i]]=true;

    

    top=2;

    s[1]=n;s[2]=n-1;

    for (int i=n-2;i;i--)

    {

        while (top>1 && cross(s[top-1],s[top],i)<0) top--;

        s[++top]=i;

        }

    for (int i=1;i<=top;i++)

        if (!v[s[i]]) a[++cnt]=s[i];

    }

    

bool cmp(point a,point b)

{

    if (a.y!=b.y) return a.y<b.y;

    return a.x<b.x;

    }

int dis(point i,point j)

{

    return (i.x-j.x)*(i.x-j.x)+(i.y-j.y)*(i.y-j.y);

    }

int main()

{

    freopen("in","r",stdin);

    scanf("%d",&n);

    for (int i=1;i<=n;i++)

        scanf("%d%d",&p[i].x,&p[i].y);

    sort(p+1,p+n+1,cmp);

    graham();

    int ans=0;

    for (int i=1;i<cnt;i++)

        for (int j=i+1;j<=cnt;j++)

            ans=max(ans,dis(p[a[i]],p[a[j]]));

    printf("%d",ans);

    }

你可能感兴趣的:(test)