二维凸包
#include <cmath>
#include <cstdio>
#include <algorithm>
const int N = 1e5 + 5;
struct Node {
double x, y;
}a[N], stk[N];
int n, tp, k;
double ans;
bool operator < (const Node &a, const Node &b) {
return a.x != b.x ? a.x < b.x : a.y < b.y;
}
double Cross(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 a, Node b) {
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i)
scanf("%lf%lf", &a[i].x, &a[i].y);
std::sort(a + 1, a + n + 1);
stk[k = ++tp] = a[1];
for (int i = 2; i <= n; ++i) {
while (tp > k && Cross(stk[tp-1], stk[tp], a[i]) <= 0) tp--;
stk[++tp] = a[i];
}
k = tp;
for (int i = n - 1; i >= 1; --i) {
while (tp > k && Cross(stk[tp-1], stk[tp], a[i]) <= 0) tp--;
stk[++tp] = a[i];
}
for (int i = 1; i < tp; ++i)
ans += Dis(stk[i], stk[i+1]);
printf("%.2lf\n", ans);
return 0;
}
半平面交
#include <cmath>
#include <cstdio>
#include <algorithm>
const int N = 505;
const double eps = 1e-14;
int read(int x = 0, int f = 1, char c = getchar()) {
for (; c < '0' || c > '9'; c = getchar())
if (c == '-') f = -1;
for (; c >='0' && c <='9'; c = getchar())
x = x * 10 + c - '0';
return x * f;
}
int Dbcmp(double x) {
if (fabs(x) < eps) return 0;
return x < 0 ? -1 : 1;
}
struct Node {
double x, y;
}p[N];
Node operator + (const Node &a, const Node &b) { return (Node) {a.x + b.x, a.y + b.y}; }
Node operator - (const Node &a, const Node &b) { return (Node) {a.x - b.x, a.y - b.y}; }
double operator * (const Node &a, const Node &b) { return a.x * b.y - a.y * b.x; }
struct Line {
Node s, t; double k;
Line() {}
Line(Node a, Node b) {
s = a, t = b; a = b - a; k = atan2(a.y, a.x);
}
}a[N];
bool operator < (const Line &a, const Line &b) {
return Dbcmp(a.k - b.k) ? a.k < b.k : Dbcmp((a.t - a.s) * (b.s - a.s)) < 0;
}
int n, m, q[N];
double ans;
Node Get(const Line &a, const Line &b) {
double k = ((b.s - a.s) * (a.t - a.s)) / ((a.t - a.s) * (b.t - b.s));
Node ans = b.t - b.s; ans.x *= k; ans.y *= k;
return b.s + ans;
}
bool Right(const Line &a, const Node &b) {
return Dbcmp((a.t - a.s) * (b - a.s)) < 0;
}
int main() {
m = read();
for (int i = 1; i <= m; ++i) {
int mi = read();
p[1] = (Node) {read(), read()};
for (int j = 2; j <= mi; ++j)
p[j] = (Node) {read(), read()}, a[++n] = (Line) {p[j-1], p[j]};
a[++n] = (Line) {p[mi], p[1]};
}
std::sort(a + 1, a + n + 1);
int l = 1, r = 0; m = n; n = 0;
for (int i = 1; i <= m; ++i)
if (Dbcmp(a[i].k - a[i-1].k)) a[++n] = a[i];
for (int i = 1; i <= n; ++i) {
while (l < r && Right(a[i], Get(a[q[r]], a[q[r-1]]))) r--;
while (l < r && Right(a[i], Get(a[q[l]], a[q[l+1]]))) l++;
q[++r] = i;
}
while (l < r && Right(a[q[l]], Get(a[q[r]], a[q[r-1]]))) r--;
for (int i = l; i < r; ++i) p[i] = Get(a[q[i]], a[q[i+1]]);
p[r] = Get(a[q[r]], a[q[l]]); p[r+1] = p[l];
for (int i = l; i <= r; ++i) ans += p[i] * p[i+1];
printf("%.3lf\n", ans / 2);
return 0;
}