分析:
内部图案虽然可以凹下去,但是外壳是凸的,这样就才会更节省材料,然后发现就是求凸包周长即可。
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define pr(x) cout << #x << ": " << x << " "
#define pl(x) cout << #x << ": " << x << endl;
struct point
{
int x,y,n;
}dian[1010],stk[1010];
int n;
int dis(point a,point b){return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}//返回的是距离的平方
int cross(point p,point s,point e)
{
return (e.x-s.x)*(p.y-s.y)-(p.x-s.x)*(e.y-s.y);
}
int cmp1(const void *a,const void *b)//将点按y值从小到大x值从小到大排序,找出左下角的点
{
point *c=(point*)a,*d=(point*)b;
if(c->y==d->y)
return c->x-d->x;
return c->y-d->y;
}
int cmp2(const void *a,const void *b)//按极角从小到大排序
{
int ret;
point *c=(point*)a,*d=(point*)b;
ret=cross(*d,dian[0],*c);
if(ret!=0) return -ret;
else if(dis(*c,dian[0])>dis(*d,dian[0]))
return 1;
else return 0;
}
int tubao(point dian[],point stk[],int n)//输入的点 输出的点 输入点的个数(下标从0开始) 返回凸包上点的个数
{
int i,top=1;
qsort(dian,n,sizeof(dian[0]),cmp1);
qsort(dian+1,n-1,sizeof(dian[1]),cmp2);
stk[0]=dian[0];
stk[1]=dian[1];
//stk[2]=dian[2];
for(i=2;i<n;++i)
{
while(top>0&&cross(dian[i],stk[top-1],stk[top])<=0) --top;
stk[++top]=dian[i];
}
return top+1;
}
int main()
{
int l,i;
double ret,a;
while(scanf("%d%d",&n,&l)!=EOF)
{
for(i=0;i<n;i++)
scanf("%d%d",&dian[i].x,&dian[i].y);
n=tubao(dian,stk,n);
ret=3.1415926*l*2;
for(i=0;i<n;i++)
{
l=dis(stk[i],stk[(i+1)%n]);
a=sqrt((double)l);
ret+=a;
}
printf("%.0f\n",ret);
}
return 0;
}