POJ 2187 Beauty Contest

来源:互联网 发布:java全栈工程师是什么 编辑:程序博客网 时间:2024/05/21 19:42

分析:给你一些点,让你求距离最大的两个点之前距离的平方。首先求出凸包,然后可以枚举凸包上所有顶点的距离找到最大值,也可以用旋转卡壳来求凸包直径。后者原理网上很多,解释的也挺好,我就放下我的代码就好了。

# include <stdio.h># include <algorithm>  using namespace std;  struct point  {      int x,y;  }v[50005];  int max(int a,int b)  {      return a>b?a:b;  }  int Cross(point a,point b,point c)  {      return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);  }  int Dis2(point a,point b)  {      return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);  }  int cmp(point a,point b)  {      int t=Cross(v[0],a,b);      if(t!=0)        return t>0?1:0;      return Dis2(v[0],a)<Dis2(v[0],b);  }  int rotating_calipers(point stack[50005],int top)//旋转卡壳  {//这里stack数组从0到top依次保存的是凸包从最下角逆时针无共线的顶点的次序。      int i,p,q=1,ans=0;      top++;      for(p=0;p<top;p++)      {//寻找以p,(p+1)%top为边,距离这条边最远的点q,也就是确定了三角形的2个点,找q使得面积最大。          while(Cross(stack[p],stack[(p+1)%top],stack[(q+1)%top])>Cross(stack[p],stack[(p+1)%top],stack[q]))            q=(q+1)%top;          ans=max(ans,Dis2(stack[p],stack[q]));      }      return ans;  }  void Graham(int n)  {      int i,min,top;      point t,stack[50005];      for(i=0,min=0;i<n;i++)        if(v[i].y<v[min].y||(v[i].y==v[min].y&&v[i].x<v[min].x))          min=i;      t=v[0]; v[0]=v[min]; v[min]=t;      sort(v+1,v+n,cmp);      top=-1; stack[++top]=v[0]; stack[++top]=v[1];      for(i=2;i<n;i++)      {          while(top>0&&Cross(stack[top-1],stack[top],v[i])<=0)            top--;          stack[++top]=v[i];      }      printf("%d\n",rotating_calipers(stack,top));  }  int main()  {      int i,n;      scanf("%d",&n);      for(i=0;i<n;i++)        scanf("%d%d",&v[i].x,&v[i].y);      Graham(n);      return 0;  }


0 0