ZJU 1453(hdu 1392) Surround the Trees(凸包)

 

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1453

 

题目大意:一看就知道的是求凸包的图,不用多说,就是求凸包边缘的长度啦

 

解题思路:标准的凸包算法

 

我自己写的,40ms

 

#include <iostream> #include <cmath> #include <algorithm> #define Max 501 #define eps 1e-8 using namespace std; struct point { double x; double y; double cross; }; point stack[Max];//储存凸包边缘顶点 point points[Max]; int NumOfVertex;//顶点数 int size;//stack长度 double sum;//边缘长度 bool cmpyx(point a,point b)//按照yx坐标排序 { if(a.y==b.y) return a.x<b.x; return a.y<b.y; } bool cmpcross(point a,point b)//按照角度大小排序 { if(a.cross == b.cross) return a.x<b.x; return a.cross<b.cross; } bool judge(point first,point second,point third)//判断是否往右拐 { double x1,x2,y1,y2,result; x1 = second.x-first.x; x2 = third.x-first.x; y1 = second.y-first.y; y2 = third.y-first.y; result = x1*y2-y1*x2; if(fabs(result)<eps) result = 0; if(result<=0)//往右拐 return true; return false; } void Cross()//计算极角 { int i; double x,y; for(i=1;i<NumOfVertex;i++) { x = (points[i].x-points[0].x); y = (points[i].y-points[0].y); points[i].cross = acos((x/(sqrt(x*x+y*y)))); } } void Graham()//找出凸包顶点 { int top=0,i; sort(points,points+NumOfVertex,cmpyx); Cross(); sort(points+1,points+NumOfVertex,cmpcross); stack[0] = points[0]; size = 1; for (i=1;i<NumOfVertex;i++) { while (size>1&&judge(stack[top-1],stack[top],points[i])) { size--; top--; } stack[++top] = points[i]; size++; } } double caculate(point top, point top2)//计算凸包长度 { double x = (top.x - top2.x) * (top.x - top2.x); double y = (top.y - top2.y) * (top.y - top2.y); return sqrt(x + y); } int main() { int i; while (scanf("%d",&NumOfVertex)!=EOF&&NumOfVertex) { for(i=0;i<NumOfVertex;i++) scanf("%lf%lf",&points[i].x,&points[i].y); Graham(); sum = 0; for (i=0;i<size-1;i++) sum+=caculate(stack[i],stack[i+1]); sum+=caculate(stack[0],stack[size-1]); printf("%.2lf/n",sum); } return 0; }

 

 

别人写的,20ms(看不懂他的Graham算法,有谁知道的可以帮我注释下哦)

 

#include <iostream> #include <cmath> #include <algorithm> #define MAX 500 //可调整,现最大容纳500个点 using namespace std; class pointclass { public: double x; double y; }; bool operator<(const pointclass &a, const pointclass &b) { if (a.y == b.y) { return a.x < b.x; } return a.y < b.y; } pointclass stack[MAX]; int size; int top; double sum; void ConvexHull(pointclass point[], int node); double judge(pointclass top, pointclass top2, pointclass poi); void caculate(pointclass top, pointclass top2); int main() { int node;int i; while (scanf("%d", &node) == 1 && node) { pointclass point[MAX]; for (i=1; i<=node; i++) { scanf("%lf%lf", &point[i].x, &point[i].y); } sort(point, point + node + 1); ConvexHull(point, node); sum = 0; while (size > 1) { caculate(stack[top], stack[top-1]); top--; size--; } printf("%.2lf/n", sum); } return 0; } /** 构建凸包 **/ void ConvexHull(pointclass point[], int node) { stack[0] = point[1]; size = 1; top = 0; int i; for (i=2; i<=node; i++) { while (size > 1 && judge(stack[top], stack[top-1], point[i]) <= 0) { size--; top--; } stack[++top] = point[i]; size++; } int size2 = size; for (i=node-1; i>=1; i--) { while (size2 > size && judge(stack[top], stack[top-1], point[i]) <= 0) { size2--; top--; } stack[++top] = point[i]; size2++; } size = size2; } /** 判断叉积 **/ double judge(pointclass top, pointclass top2, pointclass poi) { double x1 = top.x - top2.x; double y1 = top.y - top2.y; double x2 = poi.x - top2.x; double y2 = poi.y - top2.y; return x1 * y2 - x2 * y1; } /** 计算距离 **/ void caculate(pointclass top, pointclass top2) { double x = (top.x - top2.x) * (top.x - top2.x); double y = (top.y - top2.y) * (top.y - top2.y); sum += sqrt(x + y); }

你可能感兴趣的:(算法)