题目链接:
POJ 1113 Wall
//228K 0MS
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <climits>
#include <cmath>
using namespace std;
const double PI=acos(-1.0);
const int MAX_N=1100;
const double EPS=1e-10;int n;
double r;struct Point{double x,y;Point () {}Point (double x,double y) : x(x),y(y) {}Point operator + (const Point& rhs) const {return Point(x+rhs.x,y+rhs.y);}Point operator - (const Point& rhs) const {return Point(x-rhs.x,y-rhs.y);}Point operator * (const double d) const {return Point(x*d,y*d);} double dot(const Point& rhs) const {return x*rhs.x+y*rhs.y;}double cross(const Point& rhs) const {return x*rhs.y-y*rhs.x;}double dis(const Point& rhs) const {return sqrt((x-rhs.x)*(x-rhs.x)+(y-rhs.y)*(y-rhs.y));}
}point[MAX_N],vertex[MAX_N];bool cmp_x(Point a,Point b)
{if(abs(a.x-b.x)<EPS) return a.y<b.y;return a.x<b.x;
}int Andrew()
{sort(point,point+n,cmp_x);int k=0;for(int i=0;i<n;i++){while( k>1 && (vertex[k-1]-vertex[k-2]).cross(point[i]-vertex[k-1]) <= 0) k--;vertex[k++]=point[i];}int m=k;//下凸包顶点数for(int i=n-2;i>=0;i--){while(k>m && (vertex[k-1]-vertex[k-2]).cross(point[i]-vertex[k-1])<=0) k--;vertex[k++]=point[i];}k--;return k;}void solve()
{int total=Andrew();double ans=0;for(int i=0;i<total;i++){ans+=vertex[i].dis(vertex[(i+1)%total]);}ans+=PI*r*2;printf("%d\n",(int)(ans+0.5));return;}int main()
{freopen("Ain.txt","r",stdin);while(~scanf("%d%lf",&n,&r)){for(int i=0;i<n;i++){scanf("%lf%lf",&point[i].x,&point[i].y);}solve();}return 0;
}