# Graham扫描法求凸包

for(i : 2->n){
do : while(stack[top] is not available) top--;

then : stack[++top] = point[i];
}

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stack>
#include<algorithm>
using namespace std;
#define PI 3.1415926
struct point
{
double x;
double y;
}data[1005],fun;
double len_fun;
double getLen(point a,point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(b.y-a.y)*(b.y-a.y));
}
double cha(point a,point b,point c)
{
return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
}
bool cmp(point a,point b)
{
double ax=atan2(a.y-fun.y,a.x-fun.x);
double bx=atan2(b.y-fun.y,b.x-fun.x);
if(ax!=bx) return ax<bx;
return a.x<b.x;
}
int main()
{
int cases; scanf("%d",&cases);
while(cases--)
{
int n,l; scanf("%d%d",&n,&l);
for(int i=0;i<n;i++)
scanf("%lf%lf",&data[i].x,&data[i].y);
fun = data[0]; int pos=0;
for(int i=0;i<n;i++)
{
if(data[i].y<fun.y || (data[i].y==fun.y&&data[i].x<fun.x))
{
fun=data[i];
pos=i;
}
}
data[pos]=data[0]; data[0]=fun;
sort(data+1,data+n,cmp);
point st[1005]; int top=1;
st[0]=data[0]; st[1]=data[1];
for(int i=2;i<n;i++)
{
while(cha(st[top-1],data[i],st[top])>0)
top--;
st[++top]=data[i];

}
double ans=0.0;
for(int i=1;i<=top;i++)
{
ans+=getLen(st[i],st[i-1]);
}
ans+=getLen(st[0],st[top]);
ans+=2*PI*(double)l;
printf("%.0lf\n",ans);
if(cases) printf("\n");
}
return 0;
}


• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120