9 12 7 24 9 30 5 41 9 80 7 50 87 22 9 45 1 50 7 0
243.06
水平序的Andrew算法:
#include<iostream> #include<cstring> #include<cmath> #include<algorithm> using namespace std; struct node { double x,y; }a[105],b[105]; double cmp(node n,node m) //先比较X坐标,在比较Y坐标(从小到大) { if(n.x != m.x) return n.x < m.x; else return n.y < m.y; } double Cross(node a,node b,node c) //计算叉积大小 { return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y); } double dis(node a,node b) //计算距离 { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } int CH(node* a,int n,node* b) { sort(a,a+n,cmp); int m=0,i; for(i=0;i<n;i++) //从左往右,选下边界 { while(m > 1 && Cross(b[m-2],b[m-1],a[i]) < 0) m--; b[m++]=a[i]; } int k=m; for(i=n-2;i>=0;i--) //从右往左,选上边界 { while(m > k && Cross(b[m-2],b[m-1],a[i]) < 0) m--; b[m++]=a[i]; } if(n >1) m--; return m; } int main() { int n; while(cin>>n) { if(n==0) break; memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); int i,j; for(i=0;i<n;i++) { cin>>a[i].x>>a[i].y; } // cout<<CH(a,n,b)<<endl; //输出所选点的总数 if(n==1) cout<<0.00<<endl; else if(n==2) printf("%.2lf\n",dis(a[0],a[1])); else { int m=CH(a,n,b); double s=0; for(i=1;i<m;i++) s+=dis(b[i-1],b[i]); s+=dis(b[0],b[m-1]); printf("%.2lf\n",s); } // for(i=0;i<CH(a,n,b);i++) //输出所选点的坐标 // cout<<b[i].x<<" "<<b[i].y<<endl; } return 0; }
HDUJ 1392 Surround the Trees 凸包,布布扣,bubuko.com
HDUJ 1392 Surround the Trees 凸包
原文地址:http://blog.csdn.net/hyccfy/article/details/37930041