题目大意:
多朵夺舵剁垛跺惰堕掇哆驮度躲踱沲咄铎裰哚缍亸仛兊兑兑。(乱码)
其实就是求个凸包,围墙在的相对原来点距离为L — 就是加个半径为L的圆面积—— 想一想,为什么。
都比较正常,加几个注释,没有特别解释的。补充一句,计算几何的精度判断是比较必要的,eps要用起来,注意。(这道里面我没用)
#include<cstdio>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cmath>
const double PI = acos(-1.0);
const int MAXN = 10000;
const double eps = 0.000001;
using namespace std;
struct point{
double x,y;
point () {}
point (int X,int Y) {x = X; y = Y;}
point operator - (const point & a) const{ return point(x-a.x,y-a.y); }
point operator + (const point & a) const{ return point(x+a.x,y+a.y); }
point operator * (const int & a) const{ return point(x*a,y*a); }
point operator * (const double & a) const{ return point(x*a,y*a); }
point operator / (const double & a) const{ return point(x/a,y/a); }
point operator / (const int & a) const{ return point(x/a,y/a); }
};
double dot(point a,point b){
return a.x * b.x + a.y * b.y;
}
double cross(point a,point b){
return a.x * b.y - a.y * b.x;
}
double dist(point a,point b){
return sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y) *(a.y - b.y));
}
point q[MAXN +10];
point t[MAXN +10];
int n,cnt,L;
bool cmp(point a,point b)
{
if(a.x == b.x) return a.y < b.y;
return a.x < b.x;
}
int main()
{
//freopen("1.in","r",stdin);
int i;
scanf("%d%d",&n,&L);
for(i = 1;i <= n;i++)
scanf("%lf%lf",&t[i].x,&t[i].y);
sort(t+1,t+1+n,cmp);//X排序,Y上假设无限远处两点,特殊的极角排序。
q[++cnt] = t[1];//X轴以上排序
for(i = 2;i <= n;i++)
{
while(cnt >= 2 && cross(q[cnt] - q[cnt - 1],t[i] - q[cnt-1]) > 0)//判断是否凹
cnt--;
q[++cnt] = t[i];
}
int cnt1 = cnt;//X轴以下排序,确保不删除上轴的。
for(i = n-1;i >= 1;i--)
{
while(cnt > cnt1 && cross(q[cnt] - q[cnt - 1],t[i] - q[cnt-1]) > 0)
cnt--;
q[++cnt] = t[i];
}
double ans = 0;
for(i = 1;i < cnt;i++)
ans += dist(q[i],q[i+1]);
ans += PI * L * 2;
printf("%.0f\n",ans);//这样比较好
//printf("%d\n",(int)(ans+0.5));
}
/*
9 100
200 400
300 400
300 300
400 300
400 400
500 400
500 200
350 200
200 200
*/