【模板】二維凸包 / [USACO5.1]圈奶牛Fencing the Cows
阿新 • • 發佈:2019-01-08
坐標系 sca printf can || The cows 模板 get
Problem surface
戳我
Meaning
坐標系內有若幹個點,問把這些點都圈起來的最小凸包周長。
這道題就是一道凸包的模板題啊,只要求出凸包後在計算就好了,給出幾個註意點
- 記得檢查是否有吧改開double的
- 最後統計答案的時候記得將最後一個點和第一個點連起來
差不多了,打的時候註意一下就好了
如果不會凸包,就先去學學一學吧,並不是很難
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