题目链接:http://poj.org/problem?id=1113
题目大意:城堡为N个点的图形,要在距离城堡L的地方建围墙,求围墙的周长。
图片转自:http://blog.youkuaiyun.com/zhengnanlee/article/details/9633357
题目其实不难,只需要求出凸包的周长再加上半径为L的圆的周长即可。
#include<cmath>
#include<cstdio>
#include<string>
#include<algorithm>
#define DB double
using namespace std;
const int maxn=1005;
DB ans;
int N,L,top,tmp,sta[maxn];
inline DB sqr_(int x) {return (DB)(x)*x;}
struct point{
int x,y;
inline int operator *(const point b) {return x*b.y-y*b.x;}
inline point operator -(const point b) {
point ret;
ret.x=x-b.x,ret.y=y-b.y;
return ret;
}
inline DB dist(point b) {return sqrt(sqr_(x-b.x)+sqr_(y-b.y));}
inline bool operator <(const point b)const{return x<b.x||x==b.x&&y<b.y;};
}p[maxn];
inline int read() {
int ret=0,f=1;char ch=getchar();
for (; !isdigit(ch); ch=getchar()) if (ch=='-') f=-f;
for (; isdigit(ch); ch=getchar()) ret=ret*10+ch-48;
return ret*f;
}
int main() {
N=read(),L=read();
for (int i=1; i<=N; i++) p[i].x=read(),p[i].y=read();
sort(p+1,p+1+N);
sta[top=1]=1;
for (int i=2; i<=N; i++) { // 凸包的下链
while (top>1&&(p[sta[top]]-p[sta[top-1]])*(p[i]-p[sta[top-1]])<=0) top--;
sta[++top]=i;
}
tmp=top;
for (int i=N; i; i--) { // 凸包的上链
while (top>tmp+1&&(p[sta[top]]-p[sta[top-1]])*(p[i]-p[sta[top-1]])<=0) top--;
sta[++top]=i;
}
for (int i=1; i<top; i++) ans+=p[sta[i]].dist(p[sta[i+1]]);
ans+=3.1415926*2*L;
printf("%.0lf",ans);
return 0;
}