集合计算:求土包子(蓝桥杯)

题目描述

平面直角坐标系中求一个凸包的周长C。

输入描述

第一行输入一个 n ,代表测试数据量

接下来 n 行输入 n 个坐标 (x,y)

输出描述

输出 C, 结果保留 6位小数

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5;

const double eps = 1e-8;
int sgn(double x){        //判断x是否等于0
    if(fabs(x) < eps)  return 0;
    else return x<0?-1:1;
}
struct Point{
    double x,y;
    Point(){}
    Point(double x, double y):x(x),y(y){}
    Point operator + (Point B){return Point(x+B.x,y+B.y);}
    Point operator - (Point B){return Point(x-B.x,y-B.y);}
    bool operator == (Point B){return sgn(x-B.x) == 0 && sgn(y-B.y) == 0;}
    bool operator < (Point B){                  //用于sort()排序
        return sgn(x-B.x)<0 || (sgn(x-B.x)==0 && sgn(y-B.y)<0);}
};
Point p[N],ch[N];    //输入点是p[],凸包顶点放在ch[]中
typedef Point Vector;
double Cross(Vector A,Vector B){return A.x*B.y - A.y*B.x;} //叉积
double Distance(Point A,Point B){return hypot(A.x-B.x,A.y-B.y);}
//Convex_hull()求凸包。凸包顶点放在ch中,返回值是凸包的顶点数
int Convex_hull(Point *p,int n,Point *ch){
    sort(p,p+n);          //对点排序:按x从小到大排序,如果x相同,按y排序
    n=unique(p,p+n)-p;   //去除重复点
    int v=0;
    //求下凸包。如果p[i]是右拐弯的,这个点不在凸包上,往回退
    for(int i=0;i<n;i++){
        while(v>1 && sgn(Cross(ch[v-1]-ch[v-2],p[i]-ch[v-2]))<=0)
            v--;
        ch[v++]=p[i];
    }
    int j=v;
    //求上凸包
    for(int i=n-2;i>=0;i--){
        while(v>j && sgn(Cross(ch[v-1]-ch[v-2],p[i]-ch[v-2]))<=0)
            v--;
        ch[v++]=p[i];
    }
    if(n>1) v--;
    return v;                   //返回值v是凸包的顶点数
}
int main(){
    int n;
    cin >>n;
    for(int i=0;i<n;i++)
        scanf("%lf%lf",&p[i].x,&p[i].y);
    int v = Convex_hull(p,n,ch);    //返回凸包的顶点数v
    double ans=0;
    if(v==1) ans=0;
    else if(v==2) ans=Distance(ch[0],ch[1]);
    else
         for(int i=0;i<v;i++)          //计算凸包周长
              ans+=Distance(ch[i],ch[(i+1)%v]);
    printf("%.6f\n",ans);
    return 0;
}

数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值