zoukankan      html  css  js  c++  java
  • 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 }

  • 相关阅读:
    解决一切日期问题的日期类
    汉诺塔类型问题解析
    窗口滑动
    大暑假集训总结(反思)
    找硬币题解
    Fiolki题解
    大逃亡题解
    Luogu6080 [USACO05DEC]Cow Patterns G
    Luogu3193 HNOI2008 GT考试
    Codeforces1355F Guess Divisors Count
  • 原文地址:https://www.cnblogs.com/acSzz/p/2660509.html
Copyright © 2011-2022 走看看