天天看點

poj1113 求凸包+計算凸包周長

經典的求凸包題,模闆題。

要求用資源最少,那肯定這個多邊形是個凸多邊形,也就是凸包。

是以先求出凸包,計算它的周長。還有就是這道題所說的,要離城牆L遠,其實就是在加上一個圓的周長,圓的半徑就是L。

都說到這了,這道題還差什麼?還差一個經典的凸包模闆!哈哈~

代碼如下:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#define eps 1e-8
#define MAX 1111
#define pi acos(-1.0)
using namespace std;
struct Point
{
    double x,y;
    Point(double x=0,double y=0):x(x),y(y) {}
};
Point point[MAX];
Point ch[MAX];
int N,L;
double ans;
typedef Point Vector;
Vector operator + (Vector A, Vector B) {return Vector(A.x+B.x,A.y+B.y);}
Vector operator - (Point A, Point B) {return Vector(A.x-B.x,A.y-B.y);}
Vector operator * (Vector A, double p) {return Vector(A.x*p,A.y*p);}
Vector operator / (Vector A, double p) {return Vector(A.x/p,A.y/p);}
bool operator < (const Point &a,const Point &b) {return a.x<b.x||(a.x==b.x&&a.y<b.y);}
int dcmp(double x)
{
    if(fabs(x)<eps) return 0;
    else return x<0?-1:1;
}
bool operator ==(const Point& a,const Point& b)
{
    return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
}
double Dot(Vector A,Vector B) {return A.x*B.x+A.y*B.y;} //點積
double Length(Vector A) {return sqrt(Dot(A,A));}  //向量長度
double Angle(Vector A,Vector B) {return acos(Dot(A,B)/Length(A)/Length(B));} //向量夾角
double Cross(Vector A,Vector B) {return A.x*B.y-A.y*B.x;} //叉積
//計算凸包,出入點數組p,個數為p,輸出點數組ch,函數傳回凸包頂點數。
//輸入不能有重複點。函數執行完之後輸入點的順序被破壞
//如果不希望在凸包的邊上有輸入點,把兩個<=改成<
//在精度要求高的時候,用dcmp比較
int ConvexHull(Point *p,int n)
{
    sort(p,p+n);
    int m=0;
    for(int i=0;i<n;i++)
    {
        while(m>1&&Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--;
        ch[m++]=p[i];
    }
    int k=m;
    for(int i=n-2;i>=0;i--)
    {
        while(m>k&&Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--;
        ch[m++]=p[i];
    }
    if(n>1) m--;
    return m;
}
void input()
{
    int i,j;
    for(i=0;i<N;i++)
    {
        scanf("%lf%lf",&point[i].x,&point[i].y);
    }
}
double cal(int n)
{
    int i,j;
    ch[n]=ch[0];
    double len=0.0;
    for(i=1;i<=n;i++)
    {
        len+=Length(ch[i]-ch[i-1]);
    }
    len+=2*pi*L;
    return len;
}
int main()
{
    int i,j,num;
    scanf("%d%d",&N,&L);
    input();
    num=ConvexHull(point,N);
    ans=cal(num);
    printf("%0.0lf\n",ans);
    return 0;
}