Convex hull: a convex polygon with all points enclosed, this convex polygon is a convex hull
1. The first to introduce a mathematical tool vector cross product
| C | = | A × b | = | A | | b | sin [alpha] ([alpha] is a, the angle between the vectors b)
The | C | parallel vectors a, b consisting of the area of the quadrangle
Here is the cross product of two vectors is determined relative positional relationship of (useful!)
The axb <0 (a counterclockwise direction in the b), bxa> 0 (b in a clockwise direction)
//求叉积 struct node{ double x ,y; node operator -( const node & s ){ return {x-s.x , y-s.y}; } }p[N] ,s[N]; inline double X( node a ,node b ){ return a.x*b.y - b.x*a.y; }
2. Graham scan method convex hull seek
1) identify all points in the lower left corner as the point most pole
//找左下边界点 int k = 1; rep( i ,2 ,n ){ if( p[i].y < p[k].y || p[i].y == p[k].y && p[i].x < p[k].x ) k = i; } swap( p[1] ,p[k] );
2) a polar angle using the cross product for ordering
// polar angle comparison BOOL CMP (& Node A, Node & B) { Double X = X-(AP [ . 1 ], BP [ . 1 ]); // cross product of vectors determined positional relationship IF (X> 0 ) return . 1 ; IF (X == 0 && DIS (A, P [ . 1 ]) <DIS (B, P [ . 1 ])) return . 1 ; return 0 ; }
// polar angle Sort Sort (P + 2 , + n-P + . 1 , CMP);
3) deposit convex hull
s is the convex hull of the stack deposit, t is the stack
By the following relationship with the cross product of the cut-off s
//将凸包存在s中 s[1] = p[1]; s[2] = p[2]; int t = 2; rep( i ,3 ,n ){ while( t >= 2 && mul( s[t-1] ,s[t] ,p[i] )<=0 )t--; s[++t] = p[i]; }
Then the convex hull would seek out
Template title:
P2742 [template] a two-dimensional convex hull / [USACO5.1] ring cow
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <set> #include <queue> #include <stack> #include <string> #include <cstring> #include <vector> #include <map> #include <unordered_map> #define mem( a ,x ) memset( a , x ,sizeof(a) ) #define rep( i ,x ,y ) for( int i = x ; i<=y ;i++ ) #define lson l ,mid ,pos<<1 #define rson mid+1 ,r ,pos<<1|1 #define Fi first #define Se second using namespace std; typedef long long ll ; typedef pair<int ,int> pii; typedef pair<ll ,int> pli; const ll inf = 0x3f3f3f3f; const int N = 1e5+5; const ll mod = 1e9+7; int n ,m; //求叉积 struct node{ double x ,y; node operator -( const node & s ){ return {x-s.x , y-s.y}; } }p[N] ,s[N]; inline double X( node a ,node b ){ return a.x*b.y - b.x*a.y; } inline double dis( node a ,node b ){ return sqrt( (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } inline double mul( node a ,node b ,node c ){ return X(b-a ,c-a); } //极角比较 bool cmp ( node &a , node &b ){ double x = X(a-p[1], BP [ . 1 ]); // cross product of vectors determined positional relationship IF (X> 0 ) return . 1 ; IF (X == 0 && DIS (A, P [ . 1 ]) <DIS (B, P [ . 1 ] )) return . 1 ; return 0 ; } // Graham scan int Graham () { // find the lower left boundary point int K = . 1 ; REP (I, 2 , n-) { IF (P [I] .y <P [K ] .y || P [I] .y == P [K] .y && P [I] .x < P [K] .x) K= I; } the swap (P [ . 1 ], P [K]); // polar angle Sort Sort (P + 2 , P + n-+ . 1 , CMP); // convex hull is present in s s [ . 1 ] = P [ . 1 ]; S [ 2 ] = P [ 2 ]; int T = 2 ; REP (I, . 3 , n-) { the while (T> = 2 && MUL (S [T- . 1 ], S [T], P [ I]) <= 0 ) T-- ; S [ ++ T] = P [I]; } return t; } int main( ){ scanf("%d" ,&n); rep( i ,1 ,n ){ scanf("%lf%lf" ,&p[i].x ,&p[i].y ); } int sz = graham( ); double ans = dis(s[1] ,s[sz]); rep( i ,1 ,sz-1 )ans += dis( s[i] ,s[i+1] ) ; printf("%.2f" ,ans); return 0; }