Title: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=20416
This question is almost pure "convex hull problem", but also let me have an entry-level understanding of the convex package.
I see the better algorithm is the Graham scanning method, with a pen simulation of the algorithm, roughly on the algorithm has been realized, so encountered a new algorithm, must not be afraid of trouble, by simulating the algorithm in-depth understanding of the mystery
Graham Scanning Method
The specific process of the Graham Scan method:
1. First determine the point P0 of the lowest Y value in all points (if there are multiple points, whichever is better). Obviously, the P0 must be the point that makes up the convex hull.
2. With P0 as the origin, the other points p1~p8 sorted in ascending order (O (NLGN)) based on the size of the polar angle (the point at which the Poles are equal, the distance from point to P0 is sorted in ascending order). According to the geometrical knowledge, the smallest point of the angle (such as P1) and the largest point of the angle (such as P8) must be the points that make up the convex hull.
3. Prepare an empty stack s, let the p0,p1 into the stack, and then start traversing p2~p8. Assuming the current traversal to P2 (the current point), then the top of the stack of two elements (P0 and P1), if the current point P2 in the vector P0 point to the left side of the P1 (or in a straight line, this can be self-determined), then will be P2 into the stack, otherwise, keep the stack top element stack until P2 is located The top two elements of the stack constitute the left side of the vector . (O (n))
Overall time complexity: O (NLGN)
Attached: For example, the process of each step of the algorithm:
#include <cstdio>#include<iostream>#include<cmath>#include<algorithm>using namespacestd;structPoint {intx, y; Point (intx=0,inty=0): X (x), Y (y) {}} p[ the];typedef Point Vector; Vectoroperator-(Point A, point B) {returnVector (a.x-b.x, a.y-b.y);}//Fork MultiplyDoubleCross (vector A, vector b) {returna.x*b.y-a.y*b.x;}//Determining the symbolic nature of floating-point numbers (+,-, 0)Const DoubleEPS = 1e-Ten;intDCMP (Doublex) { if(Fabs (x) < EPS)return 0; returnX <0? -1:1; }DoubleDist (Point A, point B) {returnsqrt ((Double) (a.x-b.x) * (a.x-b.x) + (A.Y-B.Y) * (a.y-b.y)); } BOOLCMP (point A, point B)//for Polar sorting{Vector u= a-p[0], V = b-p[0]; intSign =dcmp (Cross (U, v)); if(Sign = =0)returnDist (A, p[0]) < Dist (b, p[0]); returnSign >0;}DoubleGrahamscan (Point *a,intN) { if(n = =1)return 0; //here Zoj and Hdu are different, zoj think to take 2,hdu think not multiply, a little pit if(n = =2)return *Dist (a[0], a[1]); int*st =New int[n]; intj=0; St[j++] =0; St[j++] =1; St[j++] =2; for(intI=3; i<n; i++) { //here can be equal to, reduce unnecessary distance calculation while(DCMP (Cross (a[st[j-1]]-a[st[j-2]], a[i]-a[st[j-2]]) <=0) --J; St[j++] =i; } DoubleRET =0.0; for(intI=1; i<j; i++) {ret+ = Dist (a[st[i-1]] , a[st[i]]); } returnRET + Dist (a[st[0]], a[st[j-1]]);}intMain () {intN; while(SCANF ("%d", &n)! = EOF &&N) {intMini, miny=32767+Ten; for(intI=0; i<n; i++) {scanf ("%d%d", &p[i].x, &p[i].y); if(Miny >p[i].y) {Miny=p[i].y; Mini=i; }} swap (p[0], P[mini]); Sort (P+1, p+N, CMP); printf ("%.2lf\n", Grahamscan (P, N)); } return 0;}
Zoj-1453--surround the Trees (convex package length)