COGS 896. 圈奶牛 (凸包)

题目描述

传送门

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

题解

凸包裸题。。。。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define eps 1e-9
#define N 20003
using namespace std;
struct data{
    double x,y;
    data(double X=0,double Y=0) {
        x=X,y=Y;
    }
    bool operator <(const data &a)const {
      return x<a.x||x==a.x&&y<a.y;
    }
}a[N],c[N];
int n,m;
data operator +(data a,data b){
    return data(a.x+b.x,a.y+b.y);
}
data operator -(data a,data b){
    return data(a.x-b.x,a.y-b.y);
}
data operator *(data a,double t){
    return data(a.x*t,a.y*t);
}
data operator /(data a,double t){
    return data(a.x/t,a.y/t);
}
double dot(data a,data b)
{
    return a.x*b.x+a.y*b.y;
}
double len(data a)
{
    return sqrt(dot(a,a));
}
double cross(data a,data b){
    return a.x*b.y-a.y*b.x;
}
int dcmp(double x) 
{
    if (fabs(x)<eps) return 0;
    return x>0?1:-1;
}
void convexhull()
{
    sort(a+1,a+n+1);
    m=0;
    for (int i=1;i<=n;i++) {
        while (m>1&&dcmp(cross(c[m]-c[m-1],a[i]-c[m]))>=0) m--;
        c[++m]=a[i];
    }
    int k=m;
    for (int i=n-1;i>=1;i--) {
        while (m>k&&dcmp(cross(c[m]-c[m-1],a[i]-c[m]))>=0) m--;
        c[++m]=a[i];
    }
    if (n>1) --m;
}
int main()
{
    freopen("fc.in","r",stdin);
    freopen("fc.out","w",stdout);
    scanf("%d",&n);
    for (int i=1;i<=n;i++) scanf("%lf%lf",&a[i].x,&a[i].y);
    convexhull();
    double ans=0;
    //for (int i=1;i<=m+1;i++) printf("%.2lf %.2lf\n",c[i].x,c[i].y);
    for (int i=1;i<=m;i++) ans+=len(c[i+1]-c[i]);
    printf("%.2lf\n",ans);
} 
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define eps 1e-9
#define N 20003
using namespace std;
struct data{
    double x,y;
    data(double X=0,double Y=0) {
        x=X,y=Y;
    }
    bool operator <(const data &a)const {
      return x<a.x||x==a.x&&y<a.y;
    }
}a[N],c[N];
int n,m;
data operator +(data a,data b){
    return data(a.x+b.x,a.y+b.y);
}
data operator -(data a,data b){
    return data(a.x-b.x,a.y-b.y);
}
data operator *(data a,double t){
    return data(a.x*t,a.y*t);
}
data operator /(data a,double t){
    return data(a.x/t,a.y/t);
}
double dot(data a,data b)
{
    return a.x*b.x+a.y*b.y;
}
double len(data a)
{
    return sqrt(dot(a,a));
}
double cross(data a,data b){
    return a.x*b.y-a.y*b.x;
}
int dcmp(double x) 
{
    if (fabs(x)<eps) return 0;
    return x>0?1:-1;
}
void convexhull()
{
    sort(a+1,a+n+1);
    m=0;
    for (int i=1;i<=n;i++) {
        while (m>1&&dcmp(cross(c[m]-c[m-1],a[i]-c[m]))>=0) m--;
        c[++m]=a[i];
    }
    int k=m;
    for (int i=n-1;i>=1;i--) {
        while (m>k&&dcmp(cross(c[m]-c[m-1],a[i]-c[m]))>=0) m--;
        c[++m]=a[i];
    }
    if (n>1) --m;
}
int main()
{
    freopen("fc.in","r",stdin);
    freopen("fc.out","w",stdout);
    scanf("%d",&n);
    for (int i=1;i<=n;i++) scanf("%lf%lf",&a[i].x,&a[i].y);
    convexhull();
    double ans=0;
    //for (int i=1;i<=m+1;i++) printf("%.2lf %.2lf\n",c[i].x,c[i].y);
    for (int i=1;i<=m;i++) ans+=len(c[i+1]-c[i]);
    printf("%.2lf\n",ans);
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值