[cogs 896]圈奶牛(凸包)

DESCRIPTION


农夫约翰想要建造一个围栏用来围住他的奶牛,可是他资金匮乏。他建造的围栏必须包括他的奶牛喜欢吃草的所有地点。对于给出的这些地点的坐标,计算最短的能够围住这些点的围栏的长度。

INPUT FORMAT


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

OUTPUT FORMAT


输出必须包括一个实数,表示必须的围栏的长度。答案保留两位小数。

SAMPLE INPUT


4
4 8
4 12
5 9.3
7 8

SAMPLE OUTPUT


12.00

SOLUTION


一道模板题

    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #define eps 10e-6
    using namespace std;
    struct Point{
        double x,y;
        Point(double x=0,double y=0):x(x),y(y){}
        Point operator + (const Point p)
        {
            return Point(x+p.x,y+p.y);
        }
        Point operator - (const Point p)
        {
            return Point(x-p.x,y-p.y); 
        }
    }p[10005],ch[10005];
    typedef Point Vector;
    int n;
    int dcmp(double x)
    {
        if(fabs(x)<eps)return 0;
        return x>0?1:-1;
    }
    double Cross(Vector A,Vector B)
    {
        return A.x*B.y-A.y*B.x;
    }
    double Dis(Point A,Point B)
    {
        return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
    }
    bool operator < (const Point& A,const Point& B)
    {
        if(A.x!=B.x)return A.x<B.x;
        return A.y<B.y; 
    }
    int ConvexHull()
    {
        sort(p+1,p+1+n);
        int top=0;
        for(int i=1;i<=n;i++)
        {
            while(top>1&&dcmp(Cross(p[i]-ch[top],ch[top]-ch[top-1]))<=0)top--;
            ch[++top]=p[i];
        }
        int k=top;
        for(int i=n-1;i>=1;i--)
        {
            while(top>k&&dcmp(Cross(p[i]-ch[top],ch[top]-ch[top-1]))<=0)top--;
            ch[++top]=p[i];
        }
        return top;
    }
    double PolyCirc(int m)
    {
        double c=0;
        for(int i=1;i<m;i++)
        {
            c+=Dis(ch[i+1],ch[i]);
        }
        return c;
    }
    int main()
    {
        //freopen("fc.in","rb",stdin);
        //freopen("fc.out","wb",stdout);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%lf%lf",&p[i].x,&p[i].y);
        }
        printf("%.2lf",PolyCirc(ConvexHull()));
        return 0;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值