hdu 1392 Surround the Trees(凸包模板)

求凸包的边长,最基础的凸包问题。编码的时候为了代码今后的扩展和易读,有些可优化可化简的地方没有处理。

还有,这里的凸包顶点是按逆时针顺序求的。

#include "math.h" #include <iostream> using namespace std; int N; struct Node { int x,y; }m_stack[105],position[105]; int stack_top; int CrossMutiply(Node& p1,Node& p2,Node& p3)//用于判断向量之间的方向关系 { return (p2.x-p1.x)*(p3.y-p1.y)-(p2.y-p1.y)*(p3.x-p1.x); } int Distance(Node& a,Node& b) { return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y); } int CMP(const void* a,const void* b)//起始点被放置在position[0],后面的点基于起始点排序,这是比较函数 { 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()//要求至少有2个顶点,即N>=2; { for(int i=1;i<N;i++)//找到y最小的点,y相同的情况下,选择x小的。放置在position[0]。 { Node temp; if(position[i].y<position[0].y||(position[i].y==position[0].y&&position[i].x<position[0].x)) { temp=position[i]; position[i]=position[0]; position[0]=temp; } } qsort(position+1,N-1,sizeof(position[0]),CMP);//排序 m_stack[0]=position[0];//m_stack[]中存储最后凸包上的点 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>=1,是怕出现和position[0],position[1]共线的点 stack_top--; m_stack[++stack_top]=position[i]; } } int main() { while(scanf("%d",&N)&&N) { for(int i=0;i<N;i++) { scanf("%d%d",&position[i].x,&position[i].y); } if(N==1) { printf("%.2f/n",0.); continue; } else if(N==2) { printf("%.2f/n",sqrt((double)Distance(position[0],position[1]))); continue; } Convex(); double ans=0; for(int i=0;i<stack_top;i++) { ans+=sqrt((double)Distance(m_stack[i],m_stack[i+1])); } ans+=sqrt((double)Distance(m_stack[stack_top],m_stack[0])); printf("%.2f/n",ans); } return 0; }

你可能感兴趣的:(hdu 1392 Surround the Trees(凸包模板))