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);
    }
posted @ 2012-04-18 09:36  Evan1004  阅读(153)  评论(0编辑  收藏  举报