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;
}


原文地址:https://www.cnblogs.com/keanuyaoo/p/3402532.html