自己看的懂的凸包模板

还是写了一个好懂点的凸包模板

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<iostream>
#define CLR(x) memset(x,0,sizeof(x))
#define ll long long int
#define PI acos(-1.0)
#define db double
using namespace std;

struct point
{
    int x,y;
}p[1005],s[1005];

/*叉积计算*/

int det(int x1,int y1,int x2,int y2)
{
    return x1*y2-x2*y1;
}

/* 求倒数第二个点和倒数第一个点,与倒数第一个点与当前点的叉乘*/
int cross(point o,point a,point b)
{
    return det(a.x-o.x,a.y-o.y,b.x-o.x,b.y-o.y);
}

/*求平方*/

db f(int x)
{
    return x*x*1.0;
}

/*水平排序*/

bool cmp(point a,point b)
{
    if(a.y==b.y)
        return a.x<b.x;
    return a.y<b.y;
}

db dis(point a,point b)
{
    return sqrt(f(a.x-b.x)+f(a.y-b.y));
}

int n,l;

int main()
{
    while(scanf("%d %d ",&n,&l)!=EOF)
    {
        for(int i=0;i<n;i++)
            scanf("%d %d",&p[i].x,&p[i].y);
        sort(p,p+n,cmp);
        int top=0;//正起扫一遍
        for(int i=0;i<n;i++)
        {
            while(top>=2 && cross(s[top-2],s[top-1],p[i])<0)//大于0,小于0完全看你向量的指向与谁相当于谁,
                                                             这个还是挺复杂的千万逻辑要清楚啊.
                top--;
            s[top++]=p[i];
        }
        int t=top+1;//反着再扫一遍
        for(int i=n-2;i>=0;i--)
        {
            while(top>=t && cross(s[top-2],s[top-1],p[i])<0)
                top--;
            s[top++]=p[i];
        }//凸包构建完成.
      int ans=0;
        for(int i=0;i<top-1;i++)
            ans+=dis(s[i],s[i+1]);//把凸包的所有边长求出来.
        printf("%d\n",ans);
    }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 遥远的森林里住着两只小动物,一个是兔子叫凹凹,另一只也是兔子叫凸凸。 认识的第一天 凹凹:好无聊呀,有没有一个跟我...
    思兹念兹阅读 2,829评论 34 26
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 174,827评论 25 709
  • 作业:1.学习张爱玲的外貌写作风格,写上一段。 年近五十的她保养的不错,眼角平整,皮肤光滑,少数民族特有的立体感的...
    觉者行者阅读 206评论 1 0
  • Sunny飞镜阅读 151评论 0 0
  • 沙发上传来的鼾声,在凌成三点被安静空旷的房间放大到一种恐怖的程度。 像是呼吸道正在饱受战争的蹂躏,被压抑的...
    瞳洞阅读 690评论 0 2