/*
题意:
求得n个点的凸包,然后求与凸包相距l的外圈的周长。
答案为n点的凸包周长加上半径为L的圆的周长
*/
# include <stdio.h>
# include <math.h>
# include <string.h>
# include <algorithm>
using namespace std;
# define PI acos(-1.0)
struct node
{
int x;
int y;
};
node a[1010],res[1010];
bool cmp(node a1,node a2)
{
if(a1.x==a2.x)
return a1.y<a2.y;
return a1.x<a2.x;
}
int cross(node a1,node a2,node a3)
{
return (a1.x-a3.x)*(a2.y-a3.y)-(a2.x-a3.x)*(a1.y-a3.y);
}
int convex(int n)//求凸包上的点
{
int m=0,i,j,k;
sort(a,a+n,cmp);
//求得下凸包,逆时针
//已知凸包点m个,如果新加入点为i,则向量(m-2,i)必定要在(m-2,m-1)的逆时针方向才符合凸包的性质
//若不成立,则m-1点不在凸包上。
for(i=0;i<n;i++)
{
while(m>1&&cross(res[m-1],a[i],res[m-2])<=0)
m--;
res[m++]=a[i];
}
k=m;
//求得上凸包
for(i=n-2;i>=0;i--)
{
while(m>k&&cross(res[m-1],a[i],res[m-2])<=0)
m--;
res[m++]=a[i];
}
if(n>1)
m--;
return m;
}
double length(node a1,node a2)
{
return sqrt(1.0*(a1.x-a2.x)*(a1.x-a2.x)+(a1.y-a2.y)*(a1.y-a2.y));
}
int main()
{
int t,n,i,L,m;
while(~scanf("%d",&t))
{
while(t--)
{
scanf("%d%d",&n,&L);
for(i=0;i<n;i++)
scanf("%d%d",&a[i].x,&a[i].y);
m=convex(n);
double ans=0;
for(i=1;i<m;i++)
ans+=length(res[i],res[i-1]);
ans+=length(res[0],res[m-1]);
ans+=2*PI*L;
printf("%.0lf\n",ans);
if(t)
printf("\n");
}
}
return 0;
}
hdu 1348 Wall (凸包模板)
最新推荐文章于 2022-05-02 16:27:29 发布