模板

凸包是指包围原点集的最小凸多边形的顶点组成的集合。
求凸包的时间复杂度为\(O(n\log n)\)
Graham scan算法
模板一:极角排序法

const int maxn=50010;
P ps[maxn],qs[maxn]; //ps为原点集,qs为凸包中的点集

int square_dis(P A,P B){
    return (A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y);
}

int cmp(P A,P B){
    int x=Cross(A-ps[0],B-A);
    if(x>0||(x==0 && square_dis(A,ps[0])<square_dis(B,ps[0]))) return 1;
    return 0;
}

int Graham(){
    int k=0;
    for(int i=0;i<n;i++){
        if(ps[i].y<ps[k].y || (ps[i].y==ps[k].y && ps[i].x<ps[k].x)) k=i;
    } 
    swap(ps[0],ps[k]);
    sort(ps+1,ps+n,cmp);
    int tot=2;
    qs[0]=ps[0];
    qs[1]=ps[1];
    for(int i=2;i<n;i++)
    {
        while(tot>1 && Cross(qs[tot-1]-qs[tot-2],ps[i]-qs[tot-1])<=0) tot--;
        qs[tot++]=ps[i];
    }
    return tot;
}

模板二:直角坐标排序法

bool cmp(P A,P B){
    if(A.x!=B.x) return A.x<B.x;
    return A.y<B.y;
}

vector<P> convex_hull(P* ps,int n){
    sort(ps,ps+n,cmp);
    int k=0;
    vector<P> qs(n*2);
    for(int i=0;i<n;i++){
        while(k>1 && Cross(qs[k-1]-qs[k-2],ps[i]-qs[k-1])<=0) k--;
        qs[k++]=ps[i];
    }
    for(int i=n-2,t=k;i>=0;i--){
        while(k>t && Cross(qs[k-1]-qs[k-2],ps[i]-qs[k-1])<=0) k--;
        qs[k++]=ps[i];
    }
    qs.resize(k-1);
    return qs;
}

模板题:hdu1348 Wall

posted @ 2020-07-06 23:24  fxq1304  阅读(55)  评论(0编辑  收藏  举报