凸包板子

凸包就是給你一堆點,再給你一根繩子你用這個繩子把這堆點圍起來!繩子與這些點所接觸的點叫做凸包點,圍成的圖形叫做凸包!

具體講解看這裏here

下面是我個人的板子,做了好多題的磨練證明我的板子是可以帶出門的

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
int n,tot;///n爲二維平面上點的個數,tot爲凸包上點的個數
struct Point
{
    int x,y;
    Point(double x=0,double y=0):x(x),y(y){}
}a[10009],p[10009];///p[]用來儲存凸包
typedef Point Vector;
Vector operator -(Vector A,Vector B)
{
    return Vector(A.x-B.x,A.y-B.y);
}
double dis(Point a,Point b)///距離此處沒有進行開平方!!!!!!!!!
{
   return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
double Wai(Point p0,Point p1,Point p2)  ///判斷向量p2是否在p0,p1的左邊是返回正值其他相反
{
    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
int cmp(Point p1,Point p2)///極角排序;
{
    int x=Wai(p1,p2,a[0]);
    if(x>0||(x==0&&dis(p1,a[0])<dis(p2,a[0]))) return 1;
    return 0;
}

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);
    tot=2,p[0]=a[0],p[1]=a[1];
    for(int i=2;i<n;i++)
    {
        while(tot>1&&Wai(p[tot-1],p[tot-2],a[i])>=0) tot--;
        p[tot++]=a[i];
    }
}
double c()///輸出周長
{
    double dist=0;
    for(int i=0;i<tot-1;i++)
    {
        dist+=sqrt(dis(p[i],p[i+1]));
    }
    dist+=sqrt(dis(p[tot-1],p[0]));
    return dist;
}
double s()///輸出面積
{
    double ss=0;
    for(int i=1;i<tot-1;i++)
    {
        ss+=(Wai(p[0],p[i],p[i+1])/2);
    }
    return ss;
}
int main()
{
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>a[i].x>>a[i].y;
    Graham();
    for(int i=0;i<tot;i++)
        cout<<p[i].x<<" "<<p[i].y<<endl;
    return 0;
}
/*
5
0 0
2 0
2 1
1 1
0 1
*/

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章