天天看点

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;
}