凸包 hdu1392

来源:互联网 发布:云计算应用介绍 编辑:程序博客网 时间:2024/06/05 11:32

题意:求凸包的周长

#include<cstdio>#include<iostream>#include<cmath>#include<algorithm>using namespace std;const double eps = 1e-8;const double PI = acos(-1.0);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;}//绕原点旋转角度B(弧度值),后x,y的变化void transXY(double B) {double tx = x,ty = y;x = tx*cos(B) - ty*sin(B);y = tx*sin(B) + ty*cos(B);}};double dist(Point a,Point b) {return sqrt((a-b)*(a-b));}const int MAXN = 1010;Point list[MAXN];int Stack[MAXN],top;//相对于list[0]的极角排序bool _cmp(Point p1,Point p2) {double tmp = (p1-list[0])^(p2-list[0]);if(sgn(tmp) > 0)return true;else if(sgn(tmp) == 0 && sgn(dist(p1,list[0]) - dist(p2,list[0])) <= 0)return true;else return false;}void Graham(int n) {Point p0;int k = 0;p0 = list[0];//找最下边的一个点for(int i = 1; i < n; i++) {if( (p0.y > list[i].y) || (p0.y == list[i].y && p0.x > list[i].x) ) {p0 = list[i];k = i;}}swap(list[k],list[0]);sort(list+1,list+n,_cmp);if(n == 1) {top = 1;Stack[0] = 0;return;}if(n == 2) {top = 2;Stack[0] = 0;Stack[1] = 1;return ;}Stack[0] = 0;Stack[1] = 1;top = 2;for(int i = 2; i < n; i++) {while(top > 1 &&        sgn((list[Stack[top-1]]-list[Stack[top-2]])^(list[i]-list[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",&((list+i)->x),&((list+i)->y));Graham(n);double ans=0;for(int i=1;i<top;++i)//cout<<list[Stack[i]].x<<' '<<list[Stack[i]].y<<endl;ans+=dist(list[Stack[i-1]],list[Stack[i]]);if(n>2) ans+=dist(list[Stack[0]],list[Stack[top-1]]);printf("%.2f\n",ans);}return 0;}


原创粉丝点击