zoukankan      html  css  js  c++  java
  • 凸包笔记

    在平面直角坐标系上给你一堆点,让你从中选出一些点组成一个点集,使得它们恰好能构成一个凸多边形且全部点都在这个凸多边形内(含边界),那么选出来的这个点集就叫做这些点的凸包。

    Graham算法

    叉积,极角排序啥的大家肯定都会,我就不多说了,这篇博客还是以存代码为主。

    具体思路就是先把所有点中最左下角的点拿出来(因为它必定在凸包上),然后其它点以它为原点极角排序,然后用一个栈维护凸包,数学证明和具体实现都很简单,我就不写了qwq

    由于每个点最多出入栈一次所以是线性的时间复杂度,但是要排序所以多了个$log$。。。

    时间复杂度$O(nlogn)$

    代码:

     1 #include<algorithm>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<cmath>
     6 #include<queue>
     7 #define inf 2147483647
     8 using namespace std;
     9 struct node{
    10     int x,y;
    11 }a[100001],s[100001];
    12 int n,k,top=1;
    13 double cross(node p,node p1,node p2){
    14     return (p1.x-p.x)*(p2.y-p.y)-(p1.y-p.y)*(p2.x-p.x);
    15 }
    16 double dis(node x,node y){
    17     return sqrt((x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y));
    18 }
    19 bool cmp(node p1,node p2){
    20     double t=cross(a[0],p1,p2);
    21     if(t>0||(t==0&&dis(a[0],p1)<dis(a[0],p2)))return true;
    22     return false;
    23 }
    24 void graham(){
    25     s[0]=a[0];
    26     s[1]=a[1];
    27     for(int i=2;i<n;i++){
    28         while(cross(s[top-1],s[top],a[i])<0&&top)top--;
    29         s[++top]=a[i];
    30     }
    31 }
    32 int main(){
    33     scanf("%d",&n);
    34     for(int i=0;i<n;i++){
    35         scanf("%d%d",&a[i].x,&a[i].y);
    36         if(i==0||a[i].y<a[k].y||(a[i].y==a[k].y&&a[i].x<a[k].x))k=i;
    37     }
    38     swap(a[0],a[k]);
    39     sort(a+1,a+n,cmp);
    40     graham();
    41     for(int i=0;i<=top;i++){
    42         printf("%d %d
    ",s[i].x,s[i].y);
    43     }
    44     return 0;
    45 }

    旋转卡壳

    来,大家跟我念:xuan2zhuan3qia3ke2

    就是拿两根直线“卡”着凸包,然后乱搞一下东西qwq

    几道题目(待更完):

    【BZOJ1185】【HNOI2007】最小矩形覆盖

    旋转卡壳乱搞

     1 #include<algorithm>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<cmath>
     6 #include<queue>
     7 #define inf 2147483647
     8 #define eps 1e-9
     9 using namespace std;
    10 struct node{
    11     double x,y;
    12     node(const double _x=0,const double _y=0){x=_x,y=_y;}
    13     friend bool operator <(node x,node y){return fabs(x.y-y.y)<eps?x.x<y.x:x.y<y.y;}
    14     friend bool operator ==(node x,node y){return fabs(x.x-y.x)<eps&&fabs(x.y-y.y)<eps;}
    15     friend bool operator !=(node x,node y){return !(x==y);}
    16     friend node operator +(node x,node y){return node(x.x+y.x,x.y+y.y);}
    17     friend node operator -(node x,node y){return node(x.x-y.x,x.y-y.y);}
    18     friend node operator *(node x,double y){return node(x.x*y,x.y*y);}
    19     friend double operator *(node x,node y){return x.x*y.y-x.y*y.x;}
    20     friend double operator /(node x,node y){return x.x*y.x+x.y*y.y;}
    21     friend double dis(node x,node y){return sqrt((x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y));}
    22     friend double cross(node p,node p1,node p2){return (p1-p)*(p2-p);}
    23 }a[100001],s[100001],ans[4];
    24 int n,k,l,r,now,top=1;
    25 double L,R,S,H,sq,anss=100000000000;
    26 bool cmp(node p1,node p2){
    27     double t=(p1-a[1])*(p2-a[1]);
    28     if(t>0||(fabs(t)<eps&&dis(a[1],p1)<dis(a[1],p2)))return true;
    29     return false;
    30 }
    31 
    32 int main(){
    33     scanf("%d",&n);
    34     for(int i=1;i<=n;i++){
    35         scanf("%lf%lf",&a[i].x,&a[i].y);
    36         if(i==1||a[i]<a[k])k=i;
    37     }
    38     swap(a[1],a[k]);
    39     sort(a+2,a+n+1,cmp);
    40     s[1]=a[1];
    41     for(int i=2;i<=n;i++){
    42         while(top>1&&(s[top]-s[top-1])*(a[i]-s[top])<eps)top--;
    43         s[++top]=a[i];
    44     }
    45     s[0]=s[top];
    46     l=r=now=1;
    47     for(int i=0;i<top;i++){
    48         S=dis(s[i],s[i+1]);
    49         while((s[i+1]-s[i])*(s[now+1]-s[i])-(s[i+1]-s[i])*(s[now]-s[i])>-eps)now=(now+1)%top;
    50         while((s[i+1]-s[i])/(s[r+1]-s[i])-(s[i+1]-s[i])/(s[r]-s[i])>-eps)r=(r+1)%top;
    51         if(!i)l=r;
    52         while((s[i+1]-s[i])/(s[l+1]-s[i])-(s[i+1]-s[i])/(s[l]-s[i])<eps)l=(l+1)%top;
    53         L=((s[i+1]-s[i])/(s[l]-s[i]))/S;
    54         R=((s[i+1]-s[i])/(s[r]-s[i]))/S;
    55         H=((s[i+1]-s[i])*(s[now]-s[i]))/S;
    56         if(H<0)H=-H;
    57         sq=(R-L)*H;
    58         if(sq<anss){
    59             anss=sq;
    60             ans[0]=s[i]+(s[i+1]-s[i])*(R/S);
    61             ans[1]=ans[0]+(s[r]-ans[0])*(H/dis(ans[0],s[r])); 
    62             ans[2]=ans[1]-(ans[0]-s[i])*((R-L)/dis(ans[0],s[i]));
    63             ans[3]=ans[2]+ans[0]-ans[1];
    64         }
    65     }
    66     printf("%.5lf
    ",anss);
    67     k=0;
    68     for(int i=1;i<=3;i++)if(ans[i]<ans[k])k=i;
    69     for(int i=0;i<=3;i++)printf("%.5lf %.5lf
    ",ans[(k+i)%4].x,ans[(k+i)%4].y);
    70     return 0;
    71 }
  • 相关阅读:
    Javascript进阶(7)---函数参数
    Django连接mssql(SqlServer)
    ORM查询
    Django-Model操作数据库
    Django去操作已经存在的数据库
    如何设置CentOS 7获取动态及静态IP地址
    nginx代理设置
    Django+Linux+Uwsgi+Nginx项目部署文档
    nginx的安装部署
    Django项目在linux系统中虚拟环境部署
  • 原文地址:https://www.cnblogs.com/dcdcbigbig/p/9622029.html
Copyright © 2011-2022 走看看