zoukankan      html  css  js  c++  java
  • POJ

    求凸包的面积

    const double pi = acos(-1.0);
    const int maxp = 1010;
    //`Compares a double to zero`
    int sgn(double x) {
        if (fabs(x) < eps)return 0;
        if (x < 0)return -1;
        else return 1;
    }
    
    struct Point {
        double x, y;
        Point() {}
        Point(double _x, double _y) {
            x = _x;
            y = _y;
        }
        void input() {
            scanf("%lf%lf", &x, &y);
        }
        bool operator == (Point b)const {
            return sgn(x - b.x) == 0 && sgn(y - b.y) == 0;
        }
        bool operator < (Point b)const {
            return sgn(x - b.x) == 0 ? sgn(y - b.y) < 0 : x < b.x;
        }
        Point operator -(const Point& b)const {
            return Point(x - b.x, y - b.y);
        }
        Point operator +(const Point& b)const {
            return Point(x + b.x, y + b.y);
        }
        Point operator *(const double& k)const {
            return Point(x * k, y * k);
        }
        double distance(Point p) {
            return hypot(x - p.x, y - p.y);
        }
        double operator ^(const Point& b)const {
            return x * b.y - y * b.x;
        }
    };
    
    
    struct polygon {
        int n;
        Point p[maxp];
        void input(int _n) {
            n = _n;
            for (int i = 0; i < n; i++)
                p[i].input();
        }
        void add(Point q) {
            p[n++] = q;
        }
        struct cmp {
            Point p;
            cmp(const Point& p0) { p = p0; }
            bool operator()(const Point& aa, const Point& bb) {
                Point a = aa, b = bb;
                int d = sgn((a - p) ^ (b - p));
                if (d == 0) {
                    return sgn(a.distance(p) - b.distance(p)) < 0;
                }
                return d > 0;
            }
        };
        //`进行极角排序`
        //`首先需要找到最左下角的点`
        //`需要重载号好Point的 < 操作符(min函数要用) `
        void norm() {
            Point mi = p[0];
            for (int i = 1; i < n; i++)mi = min(mi, p[i]);
            sort(p, p + n, cmp(mi));
        }
        //`得到凸包`
        //`得到的凸包里面的点编号是0$sim$n-1的`
        //`两种凸包的方法`
        //`注意如果有影响,要特判下所有点共点,或者共线的特殊情况`
        //`测试 LightOJ1203  LightOJ1239`
        void getconvex(polygon& convex) {
            sort(p, p + n);
            convex.n = n;
            for (int i = 0; i < min(n, 2); i++) {
                convex.p[i] = p[i];
            }
            if (convex.n == 2 && (convex.p[0] == convex.p[1]))convex.n--;//特判
            if (n <= 2)return;
            int& top = convex.n;
            top = 1;
            for (int i = 2; i < n; i++) {
                while (top && sgn((convex.p[top] - p[i]) ^ (convex.p[top - 1] - p[i])) <= 0)
                    top--;
                convex.p[++top] = p[i];
            }
            int temp = top;
            convex.p[++top] = p[n - 2];
            for (int i = n - 3; i >= 0; i--) {
                while (top != temp && sgn((convex.p[top] - p[i]) ^ (convex.p[top - 1] - p[i])) <= 0)
                    top--;
                convex.p[++top] = p[i];
            }
            if (convex.n == 2 && (convex.p[0] == convex.p[1]))convex.n--;//特判
            convex.norm();//`原来得到的是顺时针的点,排序后逆时针`
        }
        //`得到面积`
        double getarea() {
            double sum = 0;
            for (int i = 0; i < n; i++) {
                sum += (p[i] ^ p[(i + 1) % n]);
            }
            return fabs(sum) / 2;
        }
    };
    
    
    int main() {
        int n = readint();
        polygon p;
        p.input(n);
        polygon g;
        p.getconvex(g);
        cout << floor(g.getarea() / 50);
    }
  • 相关阅读:
    企业微信api接口调用-触发推送企业微信微信好友
    企业微信api接口调用-触发推送企业微信微信好友
    企业微信api接口调用-企业微信好友收发消息
    抖音api接口调用-同步抖音推荐的好友
    <转载>医学图像存储与传输系统(PACS)
    <转载>RESTful API 最佳实践
    <转载>DICOMweb——将DICOM影像接入互联网
    API设计规范---RESTful架构详解
    开源医学影像平台---Cornerstonejs开发指南
    开源医学影像平台---Cornerstonejs学习笔记<5>
  • 原文地址:https://www.cnblogs.com/hznumqf/p/13518209.html
Copyright © 2011-2022 走看看