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 }

 

 

 


 

posted @ 2012-08-28 17:04  Szz  阅读(266)  评论(0)    收藏  举报