易知
先求凸包,然后圆弧部分跟每个内角有关
经过计算发现圆弧总共加起来就是一个圆
#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;
}