计蒜客47——圈果树(二维凸包)

来源:互联网 发布:淘宝客服9月月度总结 编辑:程序博客网 时间:2024/04/28 07:06

传送门


小马承包了一个果园,想修一个围栏,但是不希望砍掉任何的果树。对于给出的所有的果树的坐标,计算一下最小的围住所有的果树的围栏的长度。

输入数据的第一行包括一个整数 N(0≤ N 10,000)表示农夫约翰想要围住的放牧点的数目。接下来 N 行,每行由两个由空格分隔的实数组成,Xi 和 Yi,对应平面上的放牧点坐标(-1,000,000 Xi,Yi 1,000,000)。数字用小数表示。

输出包括一个实数,表示必须的围栏的长度(保留两位有效小数


样例输入


4 
4 8
4 12
5 9.3
7 8

样例输出

12.00


解题思路:

直接计算一个二维凸包,然后计算凸包上相邻两两点的距离,然后加和就是周长。

代码:

#include <iostream>#include <cstring>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cmath>using namespace std;typedef long long LL;const double INF = 1e18+5;const int MAXN = 1e4 + 5;const double eps = 1e-10;const double PI = acos(-1.0);int double_cmp(double x){    if(fabs(x) < eps)        return 0;    if(x > 0)        return 1;    return -1;}struct Point{    double x, y;    int id;    Point() {}    Point (double _x, double _y, int i):x(_x),y(_y),id(i) {}    bool operator <(const struct Point &tmp)const    {        if(double_cmp(x-tmp.x) == 0)            return double_cmp(y-tmp.y) < 0;        return double_cmp(x-tmp.x) < 0;    }    bool operator == (const struct Point &tmp)const    {        return double_cmp(x-tmp.x)==0&&double_cmp(y-tmp.y)==0;    }} p[MAXN],st[MAXN];bool cmp(const Point& p1, const Point& p2){    return atan2(p1.y, p1.x) < atan2(p2.y, p2.x);}double XMulti(Point a, Point b, Point c)///ac X ab{    return (c.x-a.x)*(b.y-a.y) - (b.x-a.x)*(c.y-a.y);}double dis(Point a, Point b){    return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));}double dis2(Point a, Point b){    return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y);}double dot(Point a, Point b, Point c)///点积 ab . ac{    double s1 = b.x-a.x;    double t1 = b.y-a.y;    double s2 = c.x-a.x;    double t2 = c.y-a.y;    return s1*s2 + t1*t2;}int ConvexHull(Point *p, int n, Point *st)///凸包{    sort(p, p+n);    n = unique(p, p+n)-p;///去重    int m = 0;    for(int i=0; i<n; i++)    {        while(m>1 && XMulti(st[m-2],p[i],st[m-1])<=0)            m--;        st[m++] = p[i];    }    int k = m;    for(int i=n-2; i>=0; i--)    {        while(m>k && XMulti(st[m-2],p[i],st[m-1])<=0)            m--;        st[m++] = p[i];    }    if(n > 1)        m--;    return m;}int main(){    int n;    while(~scanf("%d",&n)){        for(int i=0; i<n; i++) scanf("%lf%lf",&p[i].x, &p[i].y);        int cnt = ConvexHull(p, n, st);        double sum = dis(st[0],st[cnt-1]);        for(int i=0; i<cnt-1; i++)            sum += dis(st[i], st[i+1]);        printf("%.2f\n",sum);    }    return 0;}
原创粉丝点击