POJ 2187 Beauty Contest

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

# 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值