码迷,mamicode.com
首页 > 其他好文 > 详细

Luogu 2742 二维凸包

时间:2019-02-16 19:30:09      阅读:220      评论:0      收藏:0      [点我收藏+]

标签:get   pac   ros   ++i   turn   git   tchar   向量   使用   

Luogu 2742 二维凸包

  • 使用 \(Andrew\) 算法.将点排序后分别求上下凸壳,用单调栈维护.
  • 利用向量叉积来判断当前方向.若 \(v_1\times 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\n",ans);
    return 0;
}

Luogu 2742 二维凸包

标签:get   pac   ros   ++i   turn   git   tchar   向量   使用   

原文地址:https://www.cnblogs.com/jklover/p/10388834.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!