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

题目大意:求一个点集凸包边长

题解:求凸包,直接求

卡点:发现在较后面数位上有较小的误差,还以为是浮点数误差,最后发现是构造函数写成了$int$类型

C++ Code:

#include <algorithm>
#include <cstdio>
#include <cmath>
#include <iostream>
#include <iomanip>
#define maxn 10010

inline double sqr(double x) { return x * x; }
struct Point {
	double x, y;
	Point() { }
	Point(double __x, double __y) : x(__x), y(__y) { }
	inline Point operator - (const Point &rhs) const {
		return Point(x - rhs.x, y - rhs.y);
	}
	inline Point operator + (const Point &rhs) const {
		return Point(x + rhs.x, y + rhs.y);
	}
	inline double operator * (const Point &rhs) const {
		return x * rhs.y - y * rhs.x;
	}
} O, s[maxn], v[maxn];
inline double abs2(const Point &x) { return sqr(x.x) + sqr(x.y); }
inline double dis(const Point &lhs, const Point &rhs) { return sqrt(abs2(rhs - lhs)); }
inline double det(const Point &O, const Point &lhs, const Point &rhs) {
	return (lhs - O) * (rhs - O);
}
inline bool operator < (const Point &lhs, const Point &rhs) {
	static Point X, Y; X = lhs - O, Y = rhs - O;
	static double t; t = X * Y;
	return (t > 0) || (t == 0 && abs2(X) > abs2(Y));
}

int n, tot;
int main() {
	std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
	std::cin >> n;
	if (n <= 1) {
		std::cout << "0\n";
		return 0;
	}
	int miny = 0;
	for (int i = 0; i < n; ++i) {
		std::cin >> s[i].x >> s[i].y;
		if ((s[i].y < s[miny].y) || (s[i].y == s[miny].y && s[i].x < s[miny].x)) miny = i;
	}
	if (n == 2) {
		std::cout << std::fixed << std::setprecision(2) << dis(s[0], s[1]) * 2 << '\n';
		return 0;
	}
	O = s[miny]; std::swap(s[0], s[miny]);
	std::sort(s + 1, s + n);
	v[0] = s[0], v[1] = s[1], v[2] = s[2], tot = 3;
	for (int i = 3; i < n; ++i) {
		for (Point a = v[tot - 2], b = v[tot - 1]; tot > 2 && det(a, b, s[i]) <= 0; a = v[tot - 2], b = v[tot - 1]) --tot;
		v[tot++] = s[i];
	}
	double ans = 0;
	for (int i = 0, nxt = 0; i < tot; ++i) {
		nxt += 1 - tot;
		nxt += nxt >> 31 & tot;
		ans += dis(v[i], v[nxt]);
	}
	std::cout << std::fixed << std::setprecision(2) << ans << '\n';
	return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/Memory-of-winter/p/10348966.html