zoukankan      html  css  js  c++  java
  • 凸包

    凸包就是把给定点包围在内部,面积最小的凸多边形
    Graham扫描法
    1.把点按照x坐标排序
    2.将p1,p2放到凸包中
    3.从p3开始,当新的点在凸包的前进方向的左边时加入该点,否则弹出最后加入的点,直到新点在左边
    4.将上述流程反过来做一遍求上凸壳
     
    struct vector
    {
       double x,y;
       vector (double X=0,double Y=0)
       {
           x=X,y=Y;
        }
    }
    typedef vector point;
    double cross(vector a,vector b)
    {
        return a.x*b.y-a.y*b.x;
    }
    
    
    void convexhull(point *p,int n,point *ch)  
    {  
        sort(p+1,p+n+1);  
        if (n==1){  
            ch[++m]=n;  
            return ;  
        }  
        m=1;  
        for (int i=1;i<=n;i++){  
            while (m>2&&dcmp(cross(ch[m-1]-ch[m-2],p[i]-ch[m-2]))<=0) m--;  
            ch[m++]=p[i];  
        }  
        int k=m;  
        for (int i=n-1;i>=1;i--){  
            while (m>k&&dcmp(cross(ch[m-1]-ch[m-2],p[i]-ch[m-2]))<=0) m--;  
            ch[m++]=p[i];  
        }  
        m--;  
    }  

    旋转卡壳

    求凸包上最远点对的距离

    被凸包上一对平行直线卡住的点对叫做对踵点,答案一定在对踵点上。
    按照逆时针顺序枚举凸包上一条边,则凸包上到该边所在直线最远的点也单调逆时针旋转,相当于用一条直线卡对面一个顶点

     1 double rotating_calipers(point* ch,int n)//旋转卡壳,被凸包上被一对平行直线卡住的点叫对踵点,最远点对一定在凸包的一对对踵点上  
     2 {  
     3     if (n==1)  return 0;  
     4     if (n==2)  return dot(ch[0]-ch[1],ch[0]-ch[1]);//如果只有两个点,那么就是两点的直线距离  
     5     int now=1,i;  
     6     double ans=0;  
     7     ch[n]=ch[0];  
     8     for (int i=0;i<n;i++)  
     9     {  
    10         while(dcmp(distl(ch[now],ch[i],ch[i+1])-distl(ch[now+1],ch[i],ch[i+1]))<=0)//最远点随着平行线的旋转是单调的,所以点不会来回移动  
    11           now=(now+1)%n;  
    12         ans=max(ans,dot(ch[now]-ch[i],ch[now]-ch[i]));  
    13         ans=max(ans,dot(ch[now]-ch[i+1],ch[now]-ch[i+1]));//找到与当前直线平行的最远点,用来更新答案  
    14     }  
    15     return ans;  
    16 }  

    求两凸包上的最近距离

     1 double rotating_calipers(point* p,point* q,int n,int m)//利用旋转卡壳求两个凸包上最近点的距离,一个凸包上的平行线逆时针旋转,另一个凸包上的最远点也单调逆时针旋转,所以这个算法要正反进行两遍  
     2 {  
     3     int x=0; int y=0,i;  
     4     double ans=1e10,t;  
     5     for (int i=0;i<n;i++)  
     6      x=(p[i].y<p[x].y)?i:x;  
     7     for (int i=0;i<m;i++)  
     8      y=(p[i].y>p[y].y)?i:y;  
     9     p[n]=p[0]; q[m]=q[0];  
    10     for (int i=0;i<n;i++)  
    11     {  
    12         while((t=dcmp(cross(p[x]-p[x+1],q[y+1]-q[y])))<0)//判断凸壳上下一条边的旋转方向  
    13           y=(y+1)%m;  
    14         if (t==0)//平行的时候四个点之间更新答案  
    15         {  
    16             ans=min(ans,dists(p[x],q[y+1],q[y]));  
    17             ans=min(ans,dists(p[x+1],q[y+1],q[y]));  
    18             ans=min(ans,dists(q[y],p[x],p[x+1]));  
    19             ans=min(ans,dists(q[y+1],p[x],p[x+1]));  
    20         }  
    21         else  
    22           ans=min(ans,dists(q[y],p[x],p[x+1]));//否则只用最远点更新答案  
    23         x=(x+1)%n;  
    24     }  
    25     return ans;  
    26 }  

    最小圆覆盖

    用最小的圆覆盖平面中的所有点。

     1 point center(point a,point b,point c){  
     2     point p=(a+b)/2; point q=(a+c)/2;  
     3     vector v=rotate(b-a,pi/2); vector u=rotate(c-a,pi/2);  
     4     if (dcmp(cross(v,u))==0) {  
     5         if(dcmp(len(a-b)+len(b-c)-len(a-c))==0)  
     6             return (a+c)/2;  
     7         if(dcmp(len(a-c)+len(b-c)-len(a-b))==0)  
     8             return (a+b)/2;  
     9         if(dcmp(len(a-b)+len(a-c)-len(b-c))==0)  
    10             return (b+c)/2;  
    11     }  
    12     return glt(p,v,q,u);  
    13 }  
    14 double mincc(point *p,int n,point &c)  
    15 {  
    16     random_shuffle(p,p+n);  
    17     c=p[0];  
    18     double  r=0;  
    19     int i,j,k;  
    20     for (i=1;i<n;i++)  
    21     if (dcmp(len(c-p[i])-r)>0){  
    22         c=p[i],r=0;  
    23         for (j=0;j<i;j++)  
    24         if (dcmp(len(c-p[j])-r)>0){  
    25             c=(p[i]+p[j])/2;  
    26             r=len(c-p[i]);  
    27             for (k=0;k<j;k++)  
    28             if (dcmp(len(c-p[k])-r)>0){   
    29               c=center(p[i],p[j],p[k]);  
    30               r=len(c-p[i]);  
    31             }  
    32         }  
    33     }  
    34     return r;  
    35 }  
  • 相关阅读:
    考勤助手——基于CS三层结构的子系统设计
    淘宝网架构分析——反向代理
    软件架构风格——解释器风格详析
    软件架构风格
    考勤助手类图的设计
    任课教师管理考勤子系统之用例图
    考勤助手ER图2.0版本所存在的问题
    关于“考勤助手”体系架构风格的选取
    浅谈CDN技术的性能与优势
    软件体系结构——解释器风格的浅解
  • 原文地址:https://www.cnblogs.com/zxz666/p/10770685.html
Copyright © 2011-2022 走看看