Luogu 2742 二维凸包

Posted jklover

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Luogu 2742 二维凸包相关的知识,希望对你有一定的参考价值。

Luogu 2742 二维凸包

  • 使用 (Andrew) 算法.将点排序后分别求上下凸壳,用单调栈维护.
  • 利用向量叉积来判断当前方向.若 (v_1 imes v_2<0) ,说明 (v_2)(v_1) 的右侧, (<0) 为左侧, (=0) 说明二者共线.
  • 参考讲解.
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mp make_pair
#define pii pair<int,int>
inline int read()
{
    int x=0;
    bool pos=1;
    char ch=getchar();
    for(;!isdigit(ch);ch=getchar())
        if(ch=='-')
            pos=0;
    for(;isdigit(ch);ch=getchar())
        x=x*10+ch-'0';
    return pos?x:-x;
}
const int MAXN=1e4+10;
struct point{
    double x,y;
    point(double x=0,double y=0):x(x),y(y) {}
};
bool cmp(const point &a,const point &b)
{
    return a.x==b.x?(a.y<b.y):(a.x<b.x);
}
struct Vector{
    double x,y;
    Vector(double x=0,double y=0):x(x),y(y) {}
};
Vector vec(point a,point b)//AB
{
    return Vector(b.x-a.x,b.y-a.y);
}
double cross(Vector a,Vector b)
{
    return a.x*b.y-a.y*b.x;
}
const double eps=1e-10;
int dcmp(double x)
{
    return fabs(x)<=eps?0:(x>0?1:-1);
}
bool judge(point s1,point s2,point p)
{
    Vector v1=vec(s2,s1),v2=vec(s1,p);
    return dcmp(cross(v1,v2))<1;
}
double dist(point a,point b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double ConvexHullCircumference(point *p,int n)
{
    int stk[MAXN],tp=0;
    int used[MAXN];
    fill(used+1,used+1+n,0);
    sort(p+1,p+1+n,cmp);
    stk[++tp]=1;
    for(int i=2;i<=n;++i)
        {
            while(tp>=2 && judge(p[stk[tp]],p[stk[tp-1]],p[i]))
                used[stk[tp--]]=0;
            used[i]=1;
            stk[++tp]=i;
        }
    int bot=tp;
    for(int i=n-1;i>=1;--i)
        {
            if(!used[i])
                {
                    while(tp>bot && judge(p[stk[tp]],p[stk[tp-1]],p[i]))
                        used[stk[tp--]]=0;
                    used[i]=1;
                    stk[++tp]=i;
                }
        }
    point Hull[MAXN];
    for(int i=1;i<=tp;++i)
        Hull[i]=p[stk[i]];
    double ans=0;
    for(int i=1;i<tp;++i)
        ans+=dist(Hull[i],Hull[i+1]);
    return ans;
}
int n;
point p[MAXN];
int main()
{
    n=read();
    for(int i=1;i<=n;++i)
        {
            double x,y;
            scanf("%lf%lf",&x,&y);
            p[i]=point(x,y);
        }
    double ans=ConvexHullCircumference(p,n);
    printf("%.2lf
",ans);
    return 0;
}

以上是关于Luogu 2742 二维凸包的主要内容,如果未能解决你的问题,请参考以下文章

模板二维凸包

P2742 [USACO5.1]圈奶牛Fencing the Cows /模板二维凸包(计算几何)(凸包)

P2742 [USACO5.1]圈奶牛Fencing the Cows /模板二维凸包(计算几何)(凸包)

P2742 [USACO5.1]圈奶牛Fencing the Cows /模板二维凸包(计算几何)(凸包)

P2742 模板二维凸包 / [USACO5.1]圈奶牛Fencing the Cows

P2742 模板二维凸包 / [USACO5.1]圈奶牛Fencing the Cows