BZOJ 1069: [SCOI2007] the largest land area

The maximum area of the convex hull necessarily appear on the
first convex hull is obtained, and then enumerate the diagonal, the remaining two points obtained by rotating stuck

#include <bits/stdc++.h>

#define db double
#define pb push_back

const db eps = 1e-10;
inline int sign(db k) { return k < -eps ? -1 : k > eps; }
inline int cmp(db k1, db k2) { return sign(k1 - k2); }

struct P {
    db x, y;
    P() {}
    P(db x, db y): x(x), y(y) {}
    P operator + (const P &p) const { return {x + p.x, y + p.y}; }
    P operator - (const P &p) const { return {x - p.x, y - p.y}; }
    P operator * (db k) const { return {x * k, y * k}; }
    P operator / (db k) const { return {x / k, y / k}; }
    bool operator < (const P &p) const { int c = cmp(x, p.x); return c ? c == -1 : cmp(y, p.y) == -1; }
    bool operator == (const P &p) const { return !cmp(x, p.x) && !cmp(y, p.y); }
    db distTo(const P &p) const { return (*this - p).abs(); }
    db alpha() { return atan2(y, x); }
    void read() { scanf("%lf%lf", &x, &y); }
    void print() { printf("%.10f %.10f\n", x, y); }
    db abs() { return sqrt(abs2()); }
    db abs2() { return x * x + y * y; }
    P rot(const db &k) { return P(x * cos(k) - y * sin(k), x * sin(k) + y * cos(k)); }
    P rot90() { return P(-y, x); }
    P unit() { return *this / abs(); }
    P normal() { return rot90() / abs(); }
    int quad() const { return sign(y) == 1 || (sign(y) == 0 && sign(x) >= 0); }
    P getdel() {if (sign(x) == -1 || (sign(x) == 0 && sign(y) == -1)) return (*this) * (-1); else return (*this);}
    db dot(const P &p) { return x * p.x + y * p.y; }
    db det(const P &p) { return x * p.y - y * p.x; }
};

inline db cross(P p1, P p2, P p3) { return ((p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y)); }
inline int crossOp(P p1, P p2, P p3) { return sign(cross(p1, p2, p3)); }
inline db cross(P p1, P p2) { return p1.x * p2.y - p1.y * p2.x; }

// 凸包
std::vector<P> convexHull(std::vector<P> ps) {
    int n = ps.size(); if (n <= 1) return ps;
    std::sort(ps.begin(), ps.end());
    std::vector<P> qs(n * 2); int k = 0;
    for (int i = 0; i < n; qs[k++] = ps[i++])
        while (k > 1 && crossOp(qs[k - 2], qs[k - 1], ps[i]) <= 0) --k;
    for (int i = n - 2, t = k; i >= 0; qs[k++] = ps[i--])
        while (k > t && crossOp(qs[k - 2], qs[k - 1], ps[i]) <= 0) --k;
    qs.resize(k - 1);
    return qs;
}
inline db area(std::vector<P> ps) {
  db ans = 0;
  for (int i = 0, n = ps.size(); i < n; i++)
    ans += ps[i].det(ps[(i + 1) % n]);
  return std::fabs(ans / 2);
}

int main() {
    int n;
    scanf("%d", &n);
    std::vector<P> ps(n);
    for (int i = 0; i < n; i++)
        ps[i].read();
    std::vector<P> qs = convexHull(ps); 
    if (qs.size() == 4) {
        printf("%.3f\n", area(qs));
        return 0;
    }
    assert(qs.size() > 4);
    n = qs.size();
    qs.resize(n + 3);
    db ans = 0;
    for (int i = 0; i < n; i++) {
        int p1 = (i + 1) % n, p2 = (i + 2) % n;
        for (int j = i + 2; j < n; j++) {
            while (cmp(cross(qs[(p1 + 1) % n], qs[j], qs[i]), cross(qs[p1], qs[j], qs[i])) > 0)
                p1 = (p1 + 1) % n;
            while (cmp(cross(qs[i], qs[j], qs[(p2 + 1) % n]), cross(qs[i], qs[j], qs[p2])) > 0)
                p2 = (p2 + 1) % n;
            ans = std::max(ans, (cross(qs[p1], qs[j], qs[i]) + cross(qs[i], qs[j], qs[p2])) / 2.0);
        }
    }
    printf("%.3f\n", ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/Mrzdtz220/p/12330964.html