求凸包的长度,先求出凸包的外围的点(求法上篇说过)。
然后求每每两个点的之间的距离就可以了。
如果求凸包的面积就可以使用。
公式是:
s1=x1*y2-y1*x2;
S=s1+s2+...s(n-1)+s(n)(共有n个点)
s/=2;
#include<stdio.h> #include<algorithm> #include<math.h> using namespace std; const int maxn=100000; int n,k,e; struct node { double x,y; } st[maxn],num[maxn]; double dis(node p1,node p2) { return (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y); } double multi(node p1,node p2,node p3) { return (p1.x-p3.x)*(p2.y-p3.y)-(p2.x-p3.x)*(p1.y-p3.y); } bool cmp(node p1,node p2) { if(multi(p1,p2,num[0])>0)return true; if(multi(p1,p2,num[0])==0&&dis(p1,num[0])<dis(p2,num[0]))return true; return false; } void Graham() { e=2; st[0]=num[0]; st[1]=num[1]; st[2]=num[2]; for(int i=3; i<n; i++) { while(e>1&&multi(num[i],st[e],st[e-1])>=0) e--; st[++e]=num[i]; } e++; st[e]=num[0]; double sum=0; for(int i=0; i<e; i++) sum+=sqrt(dis(st[i],st[i+1])); printf("%.2lf\n",sum); } int main() { while(scanf("%d",&n)!=EOF) { if(n==0) break; k=0; for(int i=0; i<n; i++) { scanf("%lf%lf",&num[i].x,&num[i].y); if(num[i].x<num[k].x||(num[i].x==num[k].x&&num[i].y<num[k].y))k=i; } if(n==1) { puts("0.00"); continue; } if(n==2) { double s=0; s=sqrt(dis(num[0],num[1])); printf("%.2lf\n",s); continue; } swap(num[0],num[k]); sort(num+1,num+n,cmp); Graham(); } return 0; } /* 8 0 0 1 0 2 0 2 1 2 2 1 2 0 2 0 1 */