分析:直接求出凸包。再算边长就可以。
另外仅仅有一个点时为0.00单独处理,两个点直接为距离也单独处理。
#include<iostream> #include<cmath> #include<algorithm> using namespace std; struct Point { Point(){} Point(double _x,double _y):x(_x),y(_y){} Point operator-(const Point& a) const { return Point(x-a.x,y-a.y); } double x,y; }; double dis(const Point& a,const Point& b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } double cross(const Point& a,const Point& b) { return a.x*b.y-a.y*b.x; } bool cmp(const Point& a,const Point& b) { if(a.x!=b.x) return a.x<b.x; else return a.y<b.y; } int convexhull(Point* p,int n,Point* ch) { int i,m,k; sort(p,p+n,cmp); m=0; for(i=0;i<n;i++) //上凸包 { while(m>1 && cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--; ch[m++]=p[i]; } k=m; for(i=n-2;i>=0;i--) //下凸包 { while(m>k && cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--; ch[m++]=p[i]; } if(n>1) m--; return m; } int main() { Point a[105],p[105]; int n,i,m; double ans; while(scanf("%d",&n)==1 &&n) { for(i=0;i<n;i++) scanf("%lf%lf",&a[i].x,&a[i].y); if(n==1) printf("0.00\n"); else if(n==2) { printf("%.2lf\n",dis(a[0],a[1])); } else { m=convexhull(a,n,p); ans=0; for(i=1;i<=m;i++) ans+=dis(p[i],p[i-1]); printf("%.2lf\n",ans); } } return 0; }
时间: 2024-12-12 21:49:53