題目鏈接:http://poj.org/problem?id=1113
題解:(盜一張圖)結合上圖, 就能很明顯的看出這道題的關鍵就是求出凸包。
結果等於:一個凸包的周長+以L爲半徑的圓的周長。
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define N 1111
#define PI 3.141592653
//定義點
struct Point
{
double x, y;
Point(double x = 0, double y = 0) : x(x), y(y) {}
};
typedef Point Vector; //Vector 爲 Point的別名
Vector operator - (Point A, Point B) {return Vector(A.x-B.x, A.y-B.y);}
double Dot(Vector A, Vector B){return A.x*B.x + A.y*B.y;}
double Length(Vector A){return sqrt(Dot(A, A));}
double Cross(Vector A, Vector B){return A.x*B.y - A.y*B.x;}
bool cmp ( Point a, Point b )
{
if ( a.x != b.x ) return a.x < b.x;
else return a.y < b.y;
}
int ConvexHull(Point *p, int n, Point * ch)
{
sort(p, p+n, cmp); //先比較x座標,在比較y座標
int m = 0;
for(int i = 0; i < n; i++)
{
while(m > 1 && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) <= 0) m--;
ch[m++] = p[i];
}
int k = m;
for(int i = n-2; i >= 0; i--)
{
while(m > k && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) <= 0) m--;
ch[m++] = p[i];
}
if(n > 1) m--;
return m;
}
int main ()
{
Point point[N], tu[N];
int n, l;
scanf("%d %d", &n, &l);
for(int i = 0; i < n; i++)
scanf("%lf %lf", &point[i].x, &point[i].y);
int cnt = ConvexHull(point, n, tu);
double ans = 2*PI*l + Length(tu[cnt]-tu[0]);
for(int i = 1; i <= cnt; i++)
ans += Length(tu[i]-tu[i-1]);
printf("%d\n", int(ans+0.5));
return 0;
}