• POJ 1113 凸包


    易知

    先求凸包,然后圆弧部分跟每个内角有关

    经过计算发现圆弧总共加起来就是一个圆

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <algorithm>
    #include <cstdlib>
    #include <cmath>
    #include <map>
    #include <sstream>
    #include <queue>
    #include <vector>
    #define MAXN 111111
    #define MAXM 211111
    #define PI acos(-1.0)
    #define eps 1e-8
    #define INF 1000000001
    using namespace std;
    int dblcmp(double d)
    {
        if (fabs(d) < eps) return 0;
        return d > eps ? 1 : -1;
    }
    struct point
    {
        double x, y;
        point(){}
        point(double _x, double _y):
        x(_x), y(_y){};
        void input()
        {
            scanf("%lf%lf",&x, &y);
        }
        double dot(point p)
        {
            return x * p.x + y * p.y;
        }
        double distance(point p)
        {
            return hypot(x - p.x, y - p.y);
        }
        point sub(point p)
        {
            return point(x - p.x, y - p.y);
        }
        double det(point p)
        {
            return x * p.y - y * p.x;
        }
        bool operator < (point a)const
        {
            return dblcmp(a.x - x) == 0 ? dblcmp(y - a.y) < 0 : x < a.x;
        }
    
    }p[MAXN];
    struct line
    {
        point a, b;
        line(){}
        line(point _a, point _b){ a = _a; b = _b;}
    };
    struct polygon
    {
        int n;
        point p[MAXN];
        line l[MAXN];
        double area;
        double circum;
        void input()
        {
            for(int i = 0; i < n; i++) p[i].input();
        }
        void getline()
        {
            for(int i = 0; i < n; i++)
                l[i] = line(p[i], p[(i + 1) % n]);
        }
        void getarea()
        {
            area = 0;
            int a = 1, b = 2;
            while(b <= n - 1)
            {
                area += p[a].sub(p[0]).det(p[b].sub(p[0]));
                a++;
                b++;
            }
            area = fabs(area) / 2;
        }
        void getcircum()
        {
            circum = 0;
            for(int i = 0; i < n; i++) circum += l[i].a.distance(l[i].b);
        }
    }convex;
    bool conpoint(point p[],int n)
    {
        for (int i = 1; i < n; i++)
            if (dblcmp(p[i].x - p[0].x) != 0 ||
                    dblcmp(p[i].y - p[0].y) != 0)
                return false;
        return true;
    }
    bool conline(point p[],int n)
    {
        for (int i = 2; i < n; i++)
            if (dblcmp(p[1].sub(p[0]).det(p[i].sub(p[0])))  != 0)   return false;
        return true;
    }
    void getconvex(point p[], int n, point res[], int& resn)
    {
        resn = 0;
        if (conpoint(p, n))
        {
            res[resn++] = p[0];
            return;
        }
        sort(p, p + n);
        if (conline(p,n))
        {
            res[resn++] = p[0];
            res[resn++] = p[n - 1];
            return;
        }
        for (int i = 0; i < n;)
            if (resn < 2 || dblcmp(res[resn - 1].sub(res[resn - 2]).det(p[i].sub(res[resn - 1]))) > 0)
                res[resn++] = p[i++];
            else --resn;
        int top = resn - 1;
        for (int i = n - 2; i >= 0;)
            if (resn < top + 2 || dblcmp(res[resn - 1].sub(res[resn - 2]).det(p[i].sub(res[resn - 1]))) > 0)
                res[resn++] = p[i--];
            else --resn;
        resn--;
    }
    double L;
    int n;
    int main()
    {
        while(scanf("%d%lf", &n, &L) != EOF)
        {
            for(int i = 0; i < n; i++) p[i].input();
            getconvex(p, n, convex.p, convex.n);
            convex.getline();
            convex.getcircum();
            printf("%d
    ", (int)(2 * L * PI + convex.circum + 0.5));
        }
        return 0;
    }


  • 相关阅读:
    BZOJ 1014 火星人prefix
    BZOJ 1013 球形空间产生器
    BZOJ 1012 最大数
    BZOJ 1011 遥远的行星
    BZOJ 1010 玩具装箱
    BZOJ 1009 GT考试
    BZOJ 1008 越狱
    BZOJ 1007 水平可见直线
    BZOJ 1006 神奇的国度
    Luogu 1450 [HAOI2008]硬币购物
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3402532.html
Copyright © 2020-2023  润新知