• 凸包板子


    凸包板子


    不需要体面的简单板子
    给出平面上n个点,求凸包周长

    采用Graham算法,用极角排序的思路来做,选取一个一定在凸包上的点,然后以这个点为原点进行计较排序,就插入节点的时候直接查看是否构成非法(违背凸包的凸),然后弹出不合法状态,就构建好凸包

    需要注意一下,这个图报一定是三个点及以上才会合法


    #include<bits/stdc++.h>
    using namespace std;
    #define N 100010
    struct Node{
        double x,y;
    }a[N],p[N];
    int n,top=1;
    double cross(Node p0,Node p1,Node p2){
        return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x);
    }
    double dis(Node p1,Node p2){
        return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
    }
    bool cmp(Node p1,Node p2){
        double z=cross(a[0],p1,p2);
        return (z>0||(z==0&&dis(a[0],p1)<dis(a[0],p2)));
    }
    void Graham(){
        int k=0;
        for(int i=0;i<n;i++)
            if(a[i].y<a[k].y||(a[i].y==a[k].y&&a[i].x<a[k].x))k=i;
        swap(a[0],a[k]);
        sort(a+1,a+n,cmp);
        p[0]=a[0];
        p[1]=a[1];
        for(int i=2;i<n;i++){
            while(cross(p[top-1],p[top],a[i])<0&&top)top--;
            p[++top]=a[i];
        }
    }
    int main(){
        scanf("%d",&n);
        for(int i=0;i<n;i++)
            scanf("%lf%lf",&a[i].x,&a[i].y);
        Graham();
        double ans;
        for(int i=0;i<top;i++)ans+=dis(p[i],p[i+1]);
        ans+=dis(p[0],p[top]);
        printf("%.2lf",ans);
        return 0;
    }
  • 相关阅读:
    详细解析Windows按键突破专家的原理
    详细解析Windows按键突破专家的原理
    简单线程注入的实现
    运用 Evince 阅读 PDF 电子书
    Sonata 0.7
    P7ZIP-Linux 中的 7Zip
    Firefox 特征扩展:Video Download
    若何在嵌入式Linux及下建造QPF字库
    Wink-Flash 演示录制软件
    自由软件:理想与实践
  • 原文地址:https://www.cnblogs.com/dream-maker-yk/p/9676396.html
Copyright © 2020-2023  润新知