二维凸包

Posted mendessy

tags:

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

二维凸包

二维凸包是计算几何的基础算法。这里是Graham算法

我们首先找到一个一定在凸包上的点,即纵坐标最小的点中,横坐标也最小的点。

然后将其他的点按照与这个点的极角排序

用栈维护,依次扫描这些排序的点

然后如果当前点和栈顶的两个点形成了凸包,就将栈顶弹出。

加入当前点

对于三点共线的情况,我们将距离远的点排在距离近的点的后面,这样在弹的时候就会将近的点弹掉,只留下远的点。

没什么细节,注意eps

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#define eps 1e-6
using namespace std;
const int maxn=1e5;
struct point{
    double x,y;
    point(double a,double b){x=a,y=b;}
    point(){x=0,y=0;}
    point operator+(const point &b)const{return point(x+b.x,y+b.y);}
    point operator-(const point &b)const{return point(x-b.x,y-b.y);}
    point operator*(const double &b)const{return point(x*b,y*b);}
    double operator*(const point &b)const{return x*b.y-y*b.x;}
    double dot()const{return x*x+y*y;}
    double dot(const point &b){return x*b.x+y*b.y;}
};
point p[maxn],q[maxn];
inline double cross(const point &a,const point &b){return a.x*b.y-a.y*b.x;}
double d(const point &a,const point &b){
//  return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    return sqrt((a-b).dot());
}
int n,cnt;
double t,ans;
inline bool cmp(point a,point b){
    double qaq=cross(a-p[1],b-p[1]);
    if(qaq>eps) return true;
    else if(fabs(qaq)<eps && d(b,p[1])-d(a,p[1])>eps) return true;
    return false;
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%lf %lf",&p[i].x,&p[i].y);
        if(i>1 && (eps<p[1].y-p[i].y || (fabs(p[i].y-p[1].y)<eps && p[i].x-p[1].x<-eps))){
            t=p[i].x;p[i].x=p[1].x;p[1].x=t;    
            t=p[i].y;p[i].y=p[1].y;p[1].y=t;    
        }
    }
    sort(p+2,p+1+n,cmp);
    q[1]=p[1];cnt++;
    for(int i=2;i<=n;i++){
        while(cnt>1 && cross(q[cnt]-q[cnt-1],p[i]-q[cnt])<-eps) cnt--;
        q[++cnt]=p[i];
    }
    q[++cnt]=p[1];
    for(int i=2;i<=cnt;i++){
        ans+=d(q[i],q[i-1]);
    }
    printf("%.2lf",ans);
    return 0;
}

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

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

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

二维凸包

二维凸包的板子

Luogu 2742 二维凸包

UVA 10652 Board Wrapping(二维凸包)