题目链接: http://poj.org/problem?id=1113
题意:给出一多边形,求出能包围这个多边形并且距第点至少L距离的图形的周长.
题目分析:凸包题,其中,距内部多边形至少L可根据圆形的性质,相当于多加了
一个r=L的圆的整个弧分开来连接凸包上所有边.
8494335 dooder_daodao 1113 Accepted 408K 32MS G++ 1350B 2011-04-15 20:24:08
#include<stdio.h> #include<stdlib.h> #include<math.h> #define M 1008 const double eps = 1e-8; const double inf = 10e8; const double Pi = acos(-1.0); typedef struct{ double x,y; }Point; Point p[M]; int stk[M]; int n,top; double l; int Sign(double x) { if(fabs(x)<eps) return 0; if(x>0) return 1; return -1; } double Dis2(Point p,Point q) { return (p.x-q.x)*(p.x-q.x)+(p.y-q.y)*(p.y-q.y); } double Multi(Point p,Point q,Point o) { return (p.x-o.x)*(q.y-o.y)-(q.x-o.x)*(p.y-o.y); } int Cmp(const void *a,const void *b) { Point *x=(Point *)a; Point *y=(Point *)b; double d=Multi(*x,*y,p[0]); if(Sign(d)==0) return Dis2(*x,p[0])>Dis2(*y,p[0])?1:-1; return d>0?-1:1; } int main() { Point tmp; int i,k; double ans; while(scanf("%d%lf",&n,&l)!=EOF){ for(i=0,k=0;i<n;i++){ scanf("%lf%lf",&p[i].x,&p[i].y); if(Sign(p[i].y-p[k].y)<0||Sign(p[i].y-p[k].y)==0&&Sign(p[i].x-p[k].x)<0) k=i; } tmp=p[k],p[k]=p[0],p[0]=tmp; qsort(p+1,n-1,sizeof(p[0]),Cmp); for(top=0;top<2;stk[top]=top++); for(i=2;i<n;i++){ while(Multi(p[stk[top-2]],p[stk[top-1]],p[i])<eps&&top>1) top--; stk[top++]=i; } for(i=0,ans=0.0;i<top;i++) ans+=sqrt(Dis2(p[stk[i]],p[stk[(i+1)%top]])); ans+=Pi*l*2; printf("%.0f/n",ans); } return 0; }