POJ 2187 Beauty Contest

来源:互联网 发布:如何卖图片知乎 编辑:程序博客网 时间:2024/05/21 20:52

 http://poj.org/problem?id=2187

旋转卡壳算法:

          所谓旋转卡壳算法是解决凸包问题的很有效的算法。下面两篇博客讲解的旋转卡壳算法很详细,我是参照这两篇博客学习的。

http://www.cnblogs.com/Booble/archive/2011/04/03/2004865.html

http://www.cnblogs.com/DreamUp/archive/2010/09/16/1828131.html

 

这道题是一道求平面上两点之间最大距离的问题,利用旋转卡壳算法可以很好的求解这个问题。听说可以用枚举的方法做出来,没试过,不知道快不快。

下面是我的代码:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>

using namespace std;

const int maxn=50005;

struct node
{
   int x,y;
  
   bool operator <(node a)const
   {
      if(y==a.y) return x<a.x;
      return y<a.y;
   }
  
}point[maxn];

int n;
int s[maxn];
int top;

//计算叉积
double det(double x1,double y1,double x2,double y2)
{return x1*y2-x2*y1;}

//计算两点之间的距离公式
int dist(node a,node b)
{return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}

//根据叉积计算两向量的位置关系
double cross(node a,node b,node c)
{return det(b.x-a.x,b.y-a.y,c.x-a.x,c.y-a.y);}

//判断double型数据与0的大小关系
int dblcmp(double x)
{
   if(fabs(x)<1e-6) return 0;
   return x>0?1:-1;
}

//Graham算法模板
void Graham()
{
   top=-1;
   s[++top]=0;
   s[++top]=1;
   for(int i=2;i<n;i++)
   {
      while(top>=1 && dblcmp(cross(point[s[top-1]],point[i],point[s[top]]))>=0)
         top--;
      s[++top]=i;
   } 
   int temp=top;
   s[++top]=n-2;
   for(int i=n-3;i>=0;i--)
   {
      while(top>=temp+1 && dblcmp(cross(point[s[top-1]],point[i],point[s[top]]))>=0)
         top--;
      s[++top]=i;
   }
}

int fun()
{
   int q=1;
   int ans=0;
   for(int i=0;i<n;i++)
   {
      //根据两个三角形面积的大小来更新点
      while(dblcmp(cross(point[s[i+1]],point[s[q]],point[s[i]])-cross(point[s[i+1]],point[s[q+1]],point[s[i]]))<0)
         q=(q+1)%top;
     
      //找到两点间的最大距离
      ans=max(ans,max(dist(point[s[q]],point[s[i+1]]),dist(point[s[q]],point[s[i]])));
   }
   return ans;
}

int main()
{
   scanf("%d",&n);
   for(int i=0;i<n;i++)
      scanf("%d%d",&point[i].x,&point[i].y);
   sort(point,point+n);
  
   //利用Gramham算法求凸包
   Graham();
  
   //在求解的凸包中求卡壳
   int ans=fun();
   printf("%d\n",ans);
   //system("pause");
  
   return 0;
}

 

原创粉丝点击