题意:求凸包的周长。
分析:凸包模板题,先按极角排好序后,然后根据叉积正负确定凸包。
#include <stdio.h> #include <math.h> #include <algorithm> #include <string.h> #include <math.h> using namespace std; const double eps = 1e-8; const int N = 110; int sgn(double x) { if(fabs(x) < eps)return 0; if(x < 0)return -1; else return 1; } struct Point { double x,y; Point(){} Point(double _x,double _y) { x = _x;y = _y; } Point operator -(const Point &b)const { return Point(x - b.x,y - b.y); } //叉积 double operator ^(const Point &b)const { return x*b.y - y*b.x; } //点积 double operator *(const Point &b)const { return x*b.x + y*b.y; } }; double dist(Point a,Point b) { return sqrt((a-b)*(a-b)); } Point p[N]; int Stack[N],top; bool cmp(Point p1,Point p2) { double tmp=(p1-p[0])^(p2-p[0]); if(sgn(tmp)==0)return sgn(dist(p[0],p1)-dist(p[0],p2))<=0; return sgn(tmp)>0; } void Graham(int n) { sort(p+1,p+n,cmp); Stack[0]=0; Stack[1]=1; top=2; for(int i=2;i<n;i++) { while(top>1&&sgn((p[Stack[top-1]]-p[Stack[top-2]])^(p[i]-p[Stack[top-2]]))<=0)top--; Stack[top++]=i; } } int main() { int n; while(scanf("%d",&n),n) { for(int i=0;i<n;i++) { scanf("%lf%lf",&p[i].x,&p[i].y); if(p[i].y<p[0].y||p[i].y==p[0].y&&p[i].x<p[0].x) swap(p[0],p[i]); } if(n==1)puts("0.00"); else if(n==2)printf("%.2lf ",dist(p[0],p[1])); else { Graham(n); double ans=0; for(int i=0;i<top;i++) ans+=dist(p[Stack[i]],p[Stack[(i+1)%top]]); printf("%.2lf ",ans); } } return 0; }