模板二维凸包 / [USACO5.1]圈奶牛Fencing the Cows

Posted hbxblog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模板二维凸包 / [USACO5.1]圈奶牛Fencing the Cows相关的知识,希望对你有一定的参考价值。

Problem surface

戳我

Meaning

坐标系内有若干个点,问把这些点都圈起来的最小凸包周长。

这道题就是一道凸包的模板题啊,只要求出凸包后在计算就好了,给出几个注意点

  1. 记得检查是否有吧改开double的
  2. 最后统计答案的时候记得将最后一个点和第一个点连起来

差不多了,打的时候注意一下就好了
如果不会凸包,就先去学学一学吧,并不是很难

Code

#include<bits/stdc++.h>
#define int long long
using namespace std;
int read(){
    int x=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9') f=(c=='-')?-1:1,c=getchar();
    while(c>='0'&&c<='9') x=x*10+c-48,c=getchar();
    return f*x;
}
struct node {
    double x,y;
}a[10011],Stack[100011];
double calc(node a,node b,node c){
       return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
}
double dis(node x,node y){
    return sqrt((x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y));
}
bool cmp(const node & x , const node & y ){
    double X=atan2(x.y-a[1].y,x.x-a[1].x);
    double Y=atan2(y.y-a[1].y,y.x-a[1].x);
    if(X==Y)
        return x.x<y.x;
    return X<Y;
}
main(){
    int n=read(),l;
    double x,y=2147483647;
    for(int i=1;i<=n;i++){
        scanf("%lf%lf",&a[i].x,&a[i].y);
        if(y>a[i].y)
            y=a[i].y,x=a[i].x,l=i;
    }
    swap(a[l],a[1]);
    int cnt=0;
    sort(a+2,a+n+1,cmp);
    Stack[++cnt]=a[1];
    for(int i=2;i<=n;i++){
        while(cnt>1&&calc(Stack[cnt-1],a[i],Stack[cnt])>=0)
            cnt--;
        Stack[++cnt]=a[i];
    }
    double ans=dis(Stack[cnt],Stack[1]);
    for(int i=2;i<=cnt;i++)
        ans+=dis(Stack[i],Stack[i-1]);
    printf("%0.2lf",ans);
}

以上是关于模板二维凸包 / [USACO5.1]圈奶牛Fencing the Cows的主要内容,如果未能解决你的问题,请参考以下文章

P2742 [USACO5.1]圈奶牛Fencing the Cows /模板二维凸包(计算几何)(凸包)

模板二维凸包 / [USACO5.1]圈奶牛Fencing the Cows

P2742 模板二维凸包 / [USACO5.1]圈奶牛Fencing the Cows

P2742 模板二维凸包 / [USACO5.1]圈奶牛Fencing the Cows

P2742 [USACO5.1]圈奶牛Fencing the Cows /模板二维凸包

P2742 模板二维凸包 / [USACO5.1]圈奶牛Fencing the Cows