凸包模板

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
const ld eps = 1e-8;
const int N = 50009;
const ld pi = acos(-1);
struct Point {
    ld x, y;
    Point(ld X = 0, ld Y = 0) { x = X, y = Y; }
    Point operator-(Point a) { return Point(x - a.x, y - a.y); }
    Point operator+(Point a) { return Point(x + a.x, y + a.y); }
    ld operator*(Point a) { return x * a.y - y * a.x; }
    ld operator^(Point a) { return x * a.x + y * a.y; }
    Point operator*(ld a) { return Point(x * a, y * a); }
    Point rotate(ld thi) {
        return Point(x * cos(thi) + y * sin(thi), -x * sin(thi) + y * cos(thi));
    }
    ld dis() { return sqrt(x * x + y * y); }
    void out() { printf("%.2Lf %.2Lf\n", x, y); }
} p[N];
int stk[N], used[N];
int dcmp(ld a, ld b) {
    if (fabs(a - b) < eps)
        return 0;
    else if (a > b)
        return 1;
    else
        return -1;
}
typedef Point Vector;
struct Line {
    Point s;
    Vector dir;
};
ld angle(Vector v1, Vector v2) { return acos(v1 ^ v2) / v1.dis() / v2.dis(); }
void out(ld x) { printf("%.2Lf\n", x); }
bool cmp(Point a, Point b ) { 
    if (dcmp(a.x, b.x)==0) { 
        return a.y > b.y;
    }
    return a.x < b.x;
}
void solve() {
    int n;
    cin >> n;
    ld a, b, r;
    cin >> a >> b >> r;
    int idn = 0;
    for (int i = 1; i <= n; i ++) {
        ld x, y, thi;
        cin >> x >> y >> thi;
        Point v1, v2, v3, v4;
        Point v = {x, y};
        v1 = {x + b/2 - r, y + a/2 - r};
        v2 = {x + b/2 - r, y - a/2 + r};
        v3 = {x - b/2 + r, y - a/2 + r};
        v4 = {x - b/2 + r, y + a/2 - r};
        v1 = v1 - v;
        v2 = v2 - v;
        v3 = v3 - v;
        v4 = v4 - v;
        v1 = v1.rotate(-thi);
        v2 = v2.rotate(-thi);
        v3 = v3.rotate(-thi);
        v4 = v4.rotate(-thi);
        p[++idn] = v1 - v;
        p[++idn] = v2 - v;
        p[++idn] = v3 - v;
        p[++idn] = v4 - v;
    }
    n = idn;
    sort(p + 1, p + 1 + n, cmp);
    int tp = 1;
    stk[tp] = 1;
    for (int i = 2; i <= n; i ++) {
        while (tp >= 2 && dcmp((p[i] - p[stk[tp]]) * (p[i] - p[stk[tp-1]]), 0) >= 0) { 
            used[stk[tp--]] = 0;
        }
        stk[++tp] = i;
        used[i] = 1;
    }
    int tmp = tp;
    for (int i = n-1; i >= 1; i--) {
        if (used[i])continue;
        while (tp >= tmp + 1 && dcmp((p[i] - p[stk[tp]]) * (p[i] - p[stk[tp-1]]), 0)  >= 0)tp--;
        stk[++tp] = i;
        used[i] = 1;
    }
    ld ans = 0;
    for (int i = 1; i < tp; i ++) {
        ans += (p[stk[i + 1]] - p[stk[i]]).dis();
    }
    printf("%.2Lf\n", ans + 2 * pi * r);
}
signed main() {
    ll t = 1;//cin >> t;
    while (t--) {
       solve();
    }
}

posted @ 2021-10-19 10:24  u_yan  阅读(24)  评论(0编辑  收藏  举报