http://poj.org/problem?id=1113
求离多边形的距离至少为L的多边形的最小周长
先求凸包
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
#define eps 1e-8
#define PI 3.1415926
#define M 2005
using namespace std;
struct point
{
int x;
int y;
}po[M],stack[M];
bool cmp(point a,point b)
{
if(a.y==b.y)
return a.x<b.x;
return a.y<b.y;
}
double Getlen(point a,point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)
+(a.y-b.y)*(a.y-b.y));
}
bool mult(point sp,point ep,point op)
{
return (sp.x-op.x)*(ep.y-op.y)>=
(ep.x-op.x)*(sp.y-op.y);
}
int Graham(point pnt[],int n,point res[])
{
int i,len,k=0,top=1;
sort(pnt,pnt+n,cmp);
if(n==0) return 0;
res[0]=pnt[0];
if(n==1) return 1;
res[1]=pnt[1];
if(n==2) return 2;
res[2]=pnt[2];
for(i=2;i<n;i++)
{
while(top && mult(pnt[i],res[top],res[top-1]))
top--;
res[++top]=pnt[i];
}
len=top;
res[++top]=pnt[n-2];
for(i=n-3;i>=0;i--)
{
while(top!=len && mult(pnt[i],res[top],res[top-1]))
top--;
res[++top]=pnt[i];
}
return top;
}
int main()
{
int i,j;
int top;
int n,L;
double sum;
__int64 sum1;
while(scanf("%d%d",&n,&L)!=EOF)
{
for(i=0;i<n;i++)
scanf("%d%d",&po[i].x,&po[i].y);
top=Graham(po,n,stack);
sum=0;
sum=sum+Getlen(stack[0],stack[top-1])*1.0;
for(i=1;i<top;i++)
{
sum=sum+Getlen(stack[i],stack[i-1]);
}
sum=sum+2*PI*L;
sum1=(__int64)sum;
if((sum-sum1*1.0)>=0.5+eps)
sum1+=1;
printf("%I64d\n",sum1);
}
return 0;
}