[USACO5.1.1]Fencing the Cows圈奶牛 求二维凸包板题
计算几何求凸包模板,没什么好说的。
luogu2742
农夫约翰想要建造一个围栏用来围住他的奶牛,可是他资金匮乏。他建造的围栏必须包括他的奶牛喜欢吃草的所有地点。对于给出的这些地点的坐标,计算最短的能够围住这些点的围栏的长度。
n 1e5
要么提出最左边点之后作为极坐标原点按照极坐标排序,要么按照x从小到大排序然后左扫一遍右扫一遍。
我们主要是判断一个折线的拐向是向外拐还是向内拐,这个可以用叉积加右手定则搞定逆时针旋转是在[0,pi](>0)还是[pi,2*pi](<0)。
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
using namespace std;
const int maxn = 3e5+5;
typedef double db;
const db eps = 1e-8;
int n;
struct node{
db x,y;
}z[maxn];
node operator-(node aa,node bb) {
return (node){aa.x-bb.x,aa.y-bb.y};
}
node operator+(node aa,node bb) {
return (node){aa.x+bb.x,aa.y+bb.y};
}
node operator*(node aa,node bb) {
return (node){aa.x*bb.x,aa.y*bb.y};
}
db operator^(node aa,node bb) {
return aa.x*bb.y - aa.y*bb.x;
}
db operator/(node aa,node bb) {
return sqrt( (aa.x-bb.x)*(aa.x-bb.x) + (aa.y-bb.y)*(aa.y-bb.y) );
}
int qe[maxn];int ql,qr;
bool cmpx(node aa,node bb) {
return aa.x < bb.x;
}
db chaji(int a,int b,int c) { //oa cha ob
node oa = z[b]-z[a]; node ob = z[c]-z[a];
return oa^ob;
}
int main() {
scanf("%d",&n);
for(int i=1;i<=n;i++) {
scanf("%lf%lf",&z[i].x,&z[i].y);
}
sort(z+1,z+1+n,cmpx);
int t = 0 , tmp;
for(int i=1;i<=n;i++) {
while(t>=2&&chaji(qe[t-1],qe[t],i)<0) t--;
qe[++t] = i;
}
for(int i=n-1;i>=1;i--) {
while(t>=2&&chaji(qe[t-1],qe[t],i)<0) t--;
qe[++t] = i;
}
db ans = 0;
for(int i=1;i<t;i++) {
ans += ( z[qe[i]]/(z[qe[i+1]]) );
}
printf("%.2f",ans);
}

浙公网安备 33010602011771号