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

计算几何……不会啊

我们定义 \(x\)\(y\) 的叉积是 \(|x||y| sin\)
用坐标表示就是 \(x1y2-x2y1\)
根据叉积可以判断两个的夹角
然后维护一个上凸壳和下凸壳,就可以求出凸包的周长了。

// by Isaunoya
#include<bits/stdc++.h>
#define int long long
using namespace std;
struct io {
	char buf[1 << 25 | 3], *s;
	int f;
	io() { f = 0, buf[fread(s = buf, 1, 1 << 25, stdin)] = '\n'; }
	io& operator >> (int&x) {
		for(x = f = 0; !isdigit(*s); ++s) f |= *s  == '-';
		while(isdigit(*s)) x = x * 10 + (*s++ ^ 48);
		return x = f ? -x : x, *this;
	}
};

struct io_out {
	char buf[1 << 25 | 3], *s = buf;
	~io_out() { fwrite(buf, 1, s - buf, stdout); }
	void write(int x) { if(x > 9) write(x / 10); *s++ = x % 10 ^ '0'; }
	io_out& operator << (int x) {
		if(x < 0) x = -x, *s++ = '-';
		write(x); return *this;
	}
	io_out& operator << (char x) { *s++ = x; return *this; }
} out;

struct point { double x, y; } ;
bool cmp(point a, point b) { return a.x < b.x; }

int n;
const int maxn = 1e5 + 51;
point p[maxn];
int st[maxn], v = 0;
double ans = 0;

double dis(int a, int b) { return sqrt((p[a].x - p[b].x) * (p[a].x - p[b].x) + (p[a].y - p[b].y) * (p[a].y - p[b].y)); }
double ChaJi(point x, point y) { return x.x * y.y - x.y * y.x; }
point operator - (point x, point y) {  return {x.x - y.x, x.y - y.y};}
double cross(int x, int y, int z) { return ChaJi(p[y] - p[x], p[z] - p[x]); }
void ins(int d) {
	while(v >= 2 && cross(st[v - 1], st[v], d) <= 0) --v;
	st[++ v] = d;
}

signed main() {
#ifdef LOCAL
	freopen("testdata.in", "r", stdin);
#endif
	ios :: sync_with_stdio(false);
	cin.tie(nullptr), cout.tie(nullptr);
	cin >> n ;
	for(int i = 1 ; i <= n ; i ++)
		cin >> p[i].x >> p[i].y;
	sort(p + 1, p + n + 1, cmp);
	st[++ v] = 1, st[++ v] = 2;
	for(int i  = 3 ; i <= n ; i ++)
		ins(i);
	for(int i = 2 ; i <= v ; i ++)
		ans += dis(st[i - 1], st[i]);
	st[v = 1] = n, st[++ v] = n - 1;
	for(int i = n - 2 ; i ; i --)
		ins(i);
	for(int i = 2 ; i <= v ; i ++)
		ans += dis(st[i - 1], st[i]);
	cout << fixed << setprecision(2) << ans << '\n';
	return 0;
}

posted @ 2020-05-02 18:24  _Isaunoya  阅读(105)  评论(0编辑  收藏  举报