zoukankan      html  css  js  c++  java
  • 凸包总结

    有关凸包的知识其实并不难理解,稍微看看便可以懂得凸包的流程与原理。

    1.什么是凸包?

        在一个实数向量空间V中,对于给定集合X,所有包含X的凸集的交集S被称为X的凸包。(来源于百度百科)

        通俗来说,凸包便是可以将平面内所有点都包括进去的凸多边形。放张图理解一下,图中红色边框框起来的便是一个凸包。

    2.怎么实现?

       凸包的实现其实十分简单。先找出平面中最下面的点(即y坐标最下的点)u,这个点肯定在凸包上。再以这个点为极点进行极角排序。什么是极角排序呢,极角排序就是以点u为坐标原点,根据所有点与点u连成的直线与x轴正方向的夹角从小到大进行排序。极角排序后,将点u与夹角最小的点加入栈中,之后依次扫描每一个点,若这个点所处的位置在栈顶点的左边,则可以加入栈中,若在右边,就弹出栈首,如此扫描,最后凸包上的点就是栈中的元素。怎么判断扫描到的点在左边还是右边呢?这便要用到叉积的知识。设a(x1,y1),b(x2,y2),c(x3,y3),那么如果x1*y2+x2*y3+x3*y1>x1*y3+x2*y1+x3*y2,就可以说明点c在直线ab的右边(直线方向a->b)。

    模板题:https://www.luogu.org/problemnew/show/P2742代码如下:

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cmath>
     4 #define rint register int
     5 using namespace std;
     6 
     7 struct node{
     8     double x,y;
     9 }a[10001];
    10 int n,p,st[10001],top;
    11 double ans,miny=2e9,minx=2e9;
    12 
    13 int cmp(node b,node c) { //极角排序 
    14     if (fabs((b.y-miny)*(c.x-minx)-(c.y-miny)*(b.x-minx))<=1e-8) return fabs(minx-b.x)<fabs(minx-c.x);
    15     return (b.y-miny)*(c.x-minx)<(c.y-miny)*(b.x-minx);
    16 }
    17 
    18 int check(int b,int c,int d) { //叉积判断 
    19     return ((a[b].x*a[c].y)+(a[c].x*a[d].y)+(a[d].x*a[b].y)-(a[b].x*a[d].y)-(a[c].x*a[b].y)-(a[d].x*a[c].y))>0;
    20 }
    21 
    22 double dist(double x1,double y1,double x2,double y2) { //计算两点间的欧几里得距离 
    23     return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
    24 }
    25 
    26 int main() {
    27     rint i;
    28     scanf("%d",&n);
    29       for (i=1;i<=n;++i) {
    30           scanf("%lf %lf",&a[i].x,&a[i].y);
    31             if (a[i].y<miny) { //寻找最下方的点 
    32                   miny=a[i].y; minx=a[i].x;
    33               }
    34       }
    35     sort(a+1,a+1+n,cmp); //极角排序 
    36     st[1]=1; st[2]=2; top=2; //将两个点加入栈中 
    37       for (i=3;i<=n;++i) { //扫描 
    38           while (!check(st[top-1],st[top],i)) top--;
    39           st[++top]=i;
    40       }
    41       for (i=2;i<=top;++i) //计算答案 
    42         ans+=dist(a[st[i-1]].x,a[st[i-1]].y,a[st[i]].x,a[st[i]].y);
    43     ans+=dist(a[st[top]].x,a[st[top]].y,a[1].x,a[st[1]].y);
    44     printf("%.2lf",ans);
    45     return 0;
    46 }
  • 相关阅读:
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    Java最常用的工具类库
    运筹学那些事,专科学生学习运筹学之网络计划技术,No.6
    这么设计实时数据平台,OLAP再也不是个事儿
    从这 5 个场景 , 看 MPC 多方安全计算的行业应用
    前后端通信进行AES加密(Vue
    圣诞快乐: 用 GaussDB T 绘制一颗圣诞树,兼论高斯数据库语法兼容
    安全多方计算新突破:阿里首次实现“公开可验证”的安全方案
    矩阵元安全多方详细介绍
    MySQL InnoDB引擎如何保证事务特性
  • 原文地址:https://www.cnblogs.com/Gaxc/p/9610900.html
Copyright © 2011-2022 走看看