Basics geometric calculation (1)

                                       Closest point on the plane && dimensional convex hull && smallest coverage circle template

  You must first know the basics of two   cross product operator overloading the base   two-dimensional cross-product can be used to determine the positional relationship between the dots and area   ( three-dimensional vector cross product algorithm may be planar)

  These templates are two-dimensional, I can not think about the problem space into a three-dimensional three-dimensional convex hull of the minimum point minimum coverage Ball

  Example P4894, P3744, P2785

   

 

        Plane closest point to explain template

 

 

 The easiest way to think of n2 violence law but you will find a range of data analysis will certainly be below t So we have an idea first and then tap the x ordering the use of the number and then merge it in the shortest distance to merge into left and right to the end the quantity becomes the shortest distance and shortest distance across the dividing line of about three cases only difficulty on the key points across the dividing line is to be able to point the distance d is smaller than the point of a few of our mission is to find and only the critical point is calculated are described in the Code

#include<bits/stdc++.h>
using namespace std;
const int maxn=1000001 ;
const int INF=2<<20;
int n,temp[maxn];
struct Point{double x,y;}S[maxn];
bool cmp(const Point &a,const Point&b ){if(a.x==b.x)return a.y<b.y; else return a.x<b.x;}
bool cmps(const int &a,const int &b){return S[a].y<S[b].y ;}
double min(double a,double b){return a<b?a:b;}
double dist(int i,int j) ///求距离
{
    double x=(S[i].x-S[j].x)*(S[i].x-S[j].x);
    double y=(S[i].y-S[j].y)*(S[i].y-S[j].y);
    return sqrt(x+y);
}

double merge(int left,int right) ///只判断x小于d&&y也小于d的点对
{
    double d=INF;
    if(left==right)
        return d ;
    if(left+1==right)
        return dist(left,right);
    int mid=left+right>>1;
    double d1=merge(left,mid) ;///
    double d2=merge(mid+1,right) ;
    D = min (D1, D2);
     int I, J, K = 0 ;
     for (I = left; I <= right; I ++ )
         IF (FABS (S [MID] .xs [I] .x) <= D ) /// selected point and the boundary point distance x is less than d 
            TEMP [K ++] = I;
    Sort (TEMP, TEMP + K, CMPS); /// Press y sort 
    for (I = 0 ; I <K; I ++ )
         for (J = I + . 1 ;. J <K && S [TEMP [J]] yS [TEMP [ . I]] y <d; J ++) /// selected points dots y distance less than d 
        {
             Double D3 = dist (TEMP [I], TEMP [J]); /// ultimately prove as long as each Analyzing no more than six points distance d * a dot matrix within the range 2d 
            IF (D> D3) D = D3;
        }
    return d;
}

int main ()
{
    scanf("%d",&n);
    for(int i=0;i<n;i++)scanf("%lf%lf",&S[i].x,&S[i].y);
    Sort (S, S + n-, CMP); /// press x sorted good division boundary 
    the printf ( " % .4lf \ n- " , Merge ( 0 , N- . 1 ));
     return  0 ;
}

 

 Two-dimensional convex hull explain template

 

 The analysis as long as we choose the outermost point combined into a graphical method is the shortest fence This is a two-dimensional convex hull at this time we have adopted is a classic Graham method algorithm key lies in how to determine a point is not convex hull constituted suggestions painting a convex hull and look at the code analysis code to write a critical comment

#include<bits/stdc++.h>
using namespace std;
int n;
struct ben
{
    double x,y;
P} [ 10005 ], S [ 10005 ];
 Double Check (Ben A1, A2 Ben, Ben B1, B2 Ben) /// checks whether the cross product is greater than 0, if it is a counterclockwise to B 
{
     return (A2. a1.x-X) * (b2.y-b1.y) - (b2.x-b1.x) * (a2.y- a1.y);
}
Double D (Ben P1, P2 Ben) /// distance between the two points 
{
     return sqrt ((p2.y-p1.y) * (p2.y-p1.y) + (P2.x-P1.x) * (p2.x- P1.x));
}
BOOL CMP (Ben P1, P2 Ben) /// sorting function that do not wrong, or else fall short 
{
     Double tmp = Check (P [ . 1 ], P1, P [ . 1 ], P2);
     IF (tmp> 0 )
         return  . 1 ;
     IF (tmp == 0 && D (P [ 0 ], P1) <D (P [ 0 ], P2))
         return  . 1 ;
     return  0 ;
}
int main ()
{

    scanf("%d",&n);
    double mid;
    for(int i=1;i<=n;i++)
    {
        Scanf ( " %% LF LF " , & P [I] .x, & P [I] .y);
         IF (! = I . 1 && P [I] .y <P [ . 1 ] .y) /// point switching p [1], the lowest point 
        {
            mid=p[1].y;p[1].y=p[i].y;p[i].y=mid;
            mid=p[1].x;p[1].x=p[i].x;p[i].x=mid;
        }
    }
    Sort (P + 2 , P + . 1 + n-, CMP); /// system using a cross product ordering fast row 
    S [ . 1 ] = P [ . 1 ]; /// lowest point in a certain projection bag 
    int CNT = . 1 ;
     for ( int I = 2 ; I <= n-; I ++) // array storage endpoint convex hull S 
    {                                                        /// judge how a point will be kicked
                                                             /// side main point is formed by a right turn left turn or 
        the while (CNT> . 1 && Check (S [the CNT- . 1 ], S [CNT], S [CNT], P [I]) <= 0 )/// determination foregoing will be kicked, kick it out of the stack if 
            cnt-- ;
        cnt++;
        s[cnt]=p[i];
    }
    S [CNT + . 1 ] = P [ . 1 ]; /// last point back to the starting point of the convex hull 
    Double ANS = 0 ;
     for ( int I = . 1 ; I <= CNT; I ++ )
        ANS + D = (S [I], S [I + . 1 ]); /// minimum length of the sides and 
    the printf ( " % .2lf \ n- " , ANS);
     return  0 ;
}

Minimum Circle - cover templates explain

 

 The key question, then it is constantly adding new points to the circle formed by now if this point is not in this circle within a circle when you meet the minimum point of this new concept it must be used in the circular boundary line with this thinking we can find three neutral point of the circle to find the hearts of circular point directly perpendicular / turn right 90 ° direction is represented by a straight line vector   

#include<bits/stdc++.h>
#define ll long long
using namespace std;

struct vec
{
    double x, y;
    vec (const double& x0 = 0, const double& y0 = 0) : x(x0), y(y0) {}///重载+-*/
    vec operator + (const vec& t) const {return vec(x+t.x, y+t.y);}
    vec operator - (const vec& t) const {return vec(x-t.x, y-t.y);}
    vec operator * (const double& t) const {return vec(x*t, y*t);}
    VEC operator / ( const  Double & T) const { return VEC (X / T, Y / T);}
     const  Double LEN2 () const { return X * X + Y * Y;}
     const  Double len () const { return sqrt (LEN2 ());} /// vector die length 
    VEC NORM () const { return * the this / len ();} /// standard vector 
    VEC rotate_90_c () { return VEC (Y, the -X-);} // / turn to the right 90 degrees 
};

double dot(const vec& a, const vec& b) {return a.x*b.x + a.y*b.y;}
double crs(const vec& a, const vec& b) {return a.x*b.y - a.y*b.x;}///叉积

vec lin_lin_int(const vec& p0, const vec& v0, const vec& p1, const vec& v1)
{
    Double T = CRS (P0-P1, V1) / CRS (V0, V1); /// using the cross product to find the intersections 
    return P0 + V0 * T;
}

Circle VEC ( const VEC A &, const VEC B &, const VEC & C) /// in the center of a straight line perpendicular request represented by a vector 
{
     return lin_lin_int ((A + B) / 2 , (BA) .rotate_90_c (), (A + C) / 2 , (the C- A) .rotate_90_c ());
}

int n;
can vec [ 100005 ]

int main ()
{
    scanf("%d", &n);
    for(int i=1; i<=n; i++) scanf("%lf%lf", &pot[i].x, &pot[i].y);
    random_shuffle (POT + . 1 , n-POT + + . 1 ); /// randomized randomized not be a big problem 
    VEC O; /// O as the center and radius r2 
    Double r2 = 0 ;
     for ( int I = . 1 ; I < n-=; I ++ )
    {
        IF ((POT [I] -o) .len2 ()> R2) /// appears a dot is not present immediately formed within the range of a new circle circle 
        {                          /// The analysis found that some point on the circle boundary 
            o = POT [I], R2 = 0 ;
             for ( int J = . 1 ; J <I; J ++ )
            {
                IF ((POT [J] -o) .len2 ()> R2) /// similar time points have been determined on the boundary of two of the 
                {
                    a = (can [i] + can [j]) / 2 , r2 = (can [j] - a) .len2 ();
                    for ( int k = 1 ; k <j; k ++ )
                    {
                        IF ((POT [K] -o) .len2 ()> R2) /// three determined circle 
                        {
                            a = circle (can [i], may [j] can [k]), R 2 = (can [k] - a) .len2 ();
                        }
                    }
                }
            }
        }
    }
    printf("%.10lf\n%.10lf %.10lf\n", sqrt(r2), o.x, o.y);
    return 0;
}

 

Last seen egg surface: light music Speak Softly, Love   

Guess you like

Origin www.cnblogs.com/yurenwuyu/p/12546389.html