首页 > 其他分享 >二维凸包构造

二维凸包构造

时间:2022-10-15 11:13:02浏览次数:54  
标签:tmp return point double 构造 凸包 二维 凸壳

凸多边形是指所有内角大小都在 \([0,\pi]\) 范围内的 简单多边形
在平面上能包含所有给定点的最小凸多边形叫做凸包。

I.jarvis数学构造法

现在平面上有这么多个点。

  1. 找到一条直线 \(l\) 过其中一点 \(A\) 并且所有其他点都在 \(l\) 的同侧,则 \(A\)必为凸包上的一点。
  2. 让 \(l\) 以 \(A\) 为轴点向一个方向不断旋转,直到 \(l\) 碰到除 \(A\) 以外的第一个点(记为 \(B\))。
  3. 再次以 \(B\) 为轴点,向相同的方向的旋转 \(l\),重复上述过程,直到 \(l\) 回到 \(A\) 点。
  4. 图形 \(ABCDEGI\) 即为一个凸包,同时这也是这个凸包的一个顶点序列。
struct point 
{
    double x;
    double y;
    point operator-(const point &p)
    {
        return (point){x-p.x,y-p.y};
    }
}p[KI];
stack<int>a;
point add(double x,double y)
{
    point s;
    s.x=x;
    s.y=y;
    return s;
}
double operator*(const point a,const point b)
{
    return a.x*b.y-b.x+a.y;
}
double clacd(point a,point b)
{
    return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
bool check(point a,point b,point c)
{
    double s=(b-a)*(c-a);
    return (s<0||(s==0 && clacd(b,a)>=clacd(c,a)))?true:false;
}
int main()
{
    int n=read();
    int cur=1;
    for(int i=1;i<=n;i++)
    {
        p[i].x=read();
        p[i].y=read();
        if(p[i].x<p[cur].x || p[i].x==p[cur].x && p[i].y<p[cur].y)
        {
            cur=i;
        }
    }
    a.push(cur);
    do
    {
        int et=1;
        for(int i=2;i<=n;i++)
        {
            if(check(p[a.top()],p[i],p[et]))
            {
                et=i;
            }
        }
        a.push(et);
    }while(a.top()!=cur);
    a.pop();
    cout<<a.size()<<'\n';
    stack<int>tmp;
    while(!a.empty())
    {
        tmp.push(a.top());
        a.pop();
    }
    while(!tmp.empty())
    {
        printf("%.2lf %.2lf\n",p[tmp.top()].x,p[tmp.top()].y);
        tmp.pop();
    }
    FINISH;
}

时间复杂度 \(\Theta(nm)\)。

II.Andrew构造法

首先把所有点以横坐标为第一关键字,纵坐标为第二关键字排序。
显然排序后最小的元素和最大的元素一定在凸包上。而且因为是凸多边形,我们如果从一个点出发逆时针走,轨迹总是“左拐”的,一旦出现右拐,就说明这一段不在凸包上。因此我们可以用一个单调栈来维护上下凸壳。
因为从左向右看,上下凸壳所旋转的方向不同,为了让单调栈起作用,我们首先 升序枚举 求出下凸壳,然后 降序 求出上凸壳。

标签:tmp,return,point,double,构造,凸包,二维,凸壳
From: https://www.cnblogs.com/SoN3ri/p/CCF_NMSL_CNMD_I_AK_CSP_NOIP_NOI_WC_CTSC_APIO_AND_IOI.html

相关文章

  • 二维表数据源可以插入数据透视表吗?
    Excel情报局职场联盟Excel生产挖掘分享Excel基础技能Excel爱好者大本营用1%的Excel基础搞定99%的职场问题做一个超级实用的Excel公众号Excel是门手艺玩转需要勇气数万Excel......
  • js关闭二维码
    关闭二维码<style>.box{width:300px;height:100px;margin:100pxauto;position:relative;......
  • Python爬虫之scrapy构造并发送请求
    scrapy数据建模与请求学习目标:应用在scrapy项目中进行建模应用构造Request对象,并发送请求应用利用meta参数在不同的解析函数中传递数据1.数据建模通常在做项目的过程中,......
  • 动手动脑--构造方法
    为什么子类的构造方法在运行之前,必须调用父类的构造方法?能不能反过来?为什么?构造函数是一种特殊的方法。主要用来在创建对象时初始化对象,即为对象成员变量赋初始值,总与ne......
  • 动手实验:继承条件下的构造方法调用
    -子类自动拥有父类声明为public和protected的成员,这就是继承特性的体现之一。-public:外界可自由访问-private:外界不可访问-protected:同一包中的子类都可以访问,另一包......
  • ASP构造大数据量的分页SQL语句
     1<%@Language = "VBScript" Codepage = "936"%> 2<% 3'分页sql语句生成代码 4Fun......
  • Java基础语法 二维数组
    二维数组packagecom.ljg.java;/**二维数组的使用:* 规定:二维数组分为外层数组的元素,内层数组的元素* int[][]arr=newint[4][3];* 外层元素:arr[0],arr[......
  • 有参无参构造器oppdemo2
    //java文件-->class文件publicclassPerson{//一个类即使什么都不写,它也会存在一个方法//显示的定义构造器Stringname;//实例化初始值//使用new关......
  • 无参构造oppdemo3
    publicclassPet{publicStringname;publicintage;//无参构造publicvoidshout(){System.out.println("叫了一声");}}publicclassA......
  • 对象、构造方法
    构造方法Python类可以使用:__init__()方法,称之为构造方法。可以实现:在创建类对象(构造类)的时候,会自动执行。在创建类对象(构造类)的时候,将传入参数自动传递给__init__......