求凸包周长。但增加了一个限制条件,所有边必须和顶点有至少L的距离。
把原始凸包上的边往外平移距离L,然后把相邻的边用圆弧连接起来,即满足要求。
往外平移的边和原始边长度相等,用原始凸包顶点坐标可以求得,那么剩下的是怎么求新加的圆弧的长度。
因为这里是凸包,所以所有圆弧加起来,恰好构成了一个半径为L的圆。
#include <math.h> #include <iostream> using namespace std; #define PI 3.141592653 int N,stack_top; struct Node { int x,y; }m_stack[1005],position[1005]; inline int CrossMutiply(Node p1,Node p2,Node p3)// 向量p1p2 X 向量p1p3 { return (p2.x-p1.x)*(p3.y-p1.y)-(p2.y-p1.y)*(p3.x-p1.x); } inline int Distance(Node p1,Node p2) { return (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y); } int CMP(const void* a,const void* b) { Node *p=(Node*)a,*q=(Node*)b; int m=CrossMutiply(position[0],*p,*q); if(m==0) return Distance(position[0],*p)-Distance(position[0],*q); else return -m; } void Convex() { int swap=0; for(int i=1;i<N;i++) { if((position[i].y<position[swap].y)||(position[i].y==position[swap].y&&position[i].x<position[swap].x)) swap=i; } Node temp=position[0]; position[0]=position[swap]; position[swap]=temp; qsort(position+1,N-1,sizeof(position[0]),CMP); m_stack[0]=position[0]; m_stack[1]=position[1]; stack_top=1; for(int i=2;i<N;i++) { while(stack_top>=1&&CrossMutiply(m_stack[stack_top-1],m_stack[stack_top],position[i])<=0) stack_top--; m_stack[++stack_top]=position[i]; } } int main() { int L; double ans; while(scanf("%d%d",&N,&L)!=EOF) { for(int i=0;i<N;i++) { scanf("%d%d",&position[i].x,&position[i].y); } Convex(); m_stack[++stack_top]=m_stack[0]; ans=0; for(int i=0;i<stack_top;i++) { ans+=sqrt((double)Distance(m_stack[i],m_stack[i+1])); } ans+=((double)L)*PI*2; printf("%d/n",(int)(ans+0.5)); } return 0; }