poj 2187 Beauty Contest (凸包: 最远点对,最长直径 , 旋转卡壳法)

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

题意:

最长的点对近距离的平方:

题解:

 旋转卡壳法, 要注意的地方是,有 所有点共线的情况,所以,(求凸包时)要将,共线点去出 ;

 

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cmath>
  4 #include<iostream>
  5 #include<algorithm>
  6 #include< set>
  7 #include<map>
  8 #include<queue>
  9 #include<vector>
 10 #include< string>
 11  #define Min(a,b) a<b?a:b
 12  #define Max(a,b) a>b?a:b
 13  #define CL(a,num) memset(a,num,sizeof(a));
 14  #define maxn  50100
 15  #define eps  1e-12
 16  #define inf 100000000
 17  #define mx 1<<60
 18  #define ll   __int64
 19  const  double pi  = acos(- 1.0);
 20  using  namespace std;
 21  struct point
 22 {
 23      double x,y;
 24 }p[maxn];
 25 point stack[maxn];
 26  int dblcmp( double x)
 27 {
 28      if(fabs(x) < eps)  return  0;
 29      if(x <  0return - 1;
 30      else  return  1;
 31 }
 32  double det( double x1, double y1, double x2, double y2)
 33 {
 34      return x1*y2 - x2*y1 ;
 35 }
 36  double cross(point a, point b, point c)
 37 {
 38      return det(b.x - a.x, b.y - a.y, c.x - a.x, c.y - a.y);
 39 }
 40  int cmp(point a,point b)
 41 {
 42      if(a.y != b.y)  return a.y < b.y;
 43      else  return a.x < b.x;
 44 }
 45  int  top ,n;
 46  void graham()
 47 {
 48 
 49      int  i,len;
 50     top =  0;
 51     sort(p,p+n,cmp);
 52 
 53      if(n ==  0return ;
 54      if(n ==  1return ;
 55     stack[top++] = p[ 0];
 56     stack[top++] = p[ 1];
 57      for(i =  2 ;i<n;i++) // 求右链
 58      {
 59          while(top >  1&& cross(stack[top -  1],stack[top -  2],p[i]) >=  0) top--;
 60 
 61         stack[top++] = p[i];
 62     }
 63 
 64       // dblcmp(cross(p[stack[top - 1]],p[stack[top - 2]],p[i])) 可以直接是 cross
 65      len =  top ;
 66 
 67      for(i = n -  2;i >=  0;i--) // 求左链
 68      {
 69           while(top > len && cross(stack[top -  1],stack[top -  2],p[i]) >=  0)top--;
 70          stack[top++] = p[i];
 71 
 72     }
 73     top--; // 第一个点入栈两次 所以 减 1
 74 
 75 }
 76  double dis(point a,point b)
 77 {
 78    double x1 = a.x;
 79    double y1 = a.y;
 80    double x2 = b.x;
 81    double y2 = b.y;
 82    return (x1 - x2)*(x1 - x2)+ (y1 - y2)*(y1 - y2);
 83 }
 84  double  rotating_calipers(point stack[], int top)
 85 {
 86      int i;
 87      int q  =  1;
 88      double ans =  0;
 89    stack[top] = stack[ 0] ;
 90 
 91 
 92     for(i =  0;i < top;i++ )
 93    {
 94         while(cross(stack[i+ 1],stack[q+ 1],stack[i]) > cross(stack[i +  1],stack[q],stack[i]))
 95         q = (q+ 1)%top;
 96 
 97 
 98 
 99        ans = max(ans,max(dis(stack[i],stack[q]),dis(stack[i+ 1],stack[q+ 1])));
100 
101    }
102     return ans ;
103 }
104  int main()
105 {
106 
107 
108        int  i,s,j;
109      // freopen("data.txt","r",stdin);
110       while(scanf( " %d ",&n)!=EOF)
111     {
112          for(i =  0;i< n;i++)
113         {
114             scanf( " %lf%lf ",&p[i].x,&p[i].y);
115         }
116         graham() ;
117 
118         double ans = rotating_calipers(stack,top);
119        printf( " %.0lf\n ",ans);
120 
121 
122     }
123 }

 

 

 


 

你可能感兴趣的:(test)