[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);
}
 
posted @ 2019-01-03 13:36  Newuser233  阅读(12)  评论(0)    收藏  举报