Titre: Portal
titre classique
La plupart du code de référence: kuangbin
#include <iostream> #include <stdio.h> #include < string .h> #include <algorithme> #include <file> #include <map> #include <vector> #include < set > #include < string > # inclure <math.h> #define LL long long #define mem (i, j) memset (i, j, sizeof (i)) #define représentant (i, j, k) pour (int i = j; i <= k; i ++) #define dep (i, j, k) pour (int i = k; i> = j; i--) #define pb push_back #definela make_pair la marque #define INF INT_MAX #define INF LLONG_MAX #define PI ACOS (-1) l'aide d' espace de noms STD; const int N = 5E5 + . 5 ; struct point { Double X, Y; Point ( Double X = 0 , Double Y = 0 ) : X (X), Y (Y) {} /// constructeur }; typedef pointer le vecteur; /// vecteur + vecteur = vecteur + vecteur = point de vecteur du vecteur opérateur + (le vecteur A, le vecteur B) { retourner le vecteur (+ Ax Bx, Ay + By);} /// Point - point = vecteur du vecteur opérateur - (Point A, Point B) { retourner le vecteur (Ax de - Bx, Ay - By);} /// vecteur * numéro de vecteur = le vecteur opérateur * (le vecteur A, Double P) { retourner le vecteur (Ax de P *, Ay * P);} /// vecteur / numéro de vecteur = le vecteur opérateur / (le vecteur A, Double P) { retourner le vecteur (Ax de / P, Ay / P);} const double EPS = 1E- 8. ; int dCMP ( Double X) { IF (FABS (X) <EPS) retour 0 ; autre retour x < 0 ? - 1 : 1 ; } Bool opérateur <( const Point & a, const Point & b) { retour ax == bx? ay <par: hache < bx; } Bool opérateur == ( const Point & a, const Point & b) { retour DCMP (ax - bx) == 0 && DCMP (ay - par) == 0 ; } Double de Dot (Vector A, B Vector) { retour Ax * Bx + Ay * By; }// produit scalaire double la longueur (le vecteur A) { retour sqrt ( 1.0 * Dot (A, A));} /// longueur de vecteur calculé Double Angle (le vecteur A, le vecteur B) { retour ACOS (Dot (A, B ) / la longueur (A) / la longueur (B));} /// vecteur A, angle B Double Cross (le vecteur A, le vecteur B) { retour Ax de * By - Ay * Bx;} /// produit croisé int , enveloppe convexe (point * P, int n-, point * CH) { Tri (P, P + n-); int m = 0 ; REP (I, 0 , n-- . 1 ) { tandis que (m> 1 && Cross (ch [m - 1 ] - CH [m - 2 ], p [i] - ch [m - 2 ]) <= 0 ) M-- ; ch [m ++] = p [i]; } Int k = m; dep (i, 0 , n - 2 ) { pendant que (m> k && Cross (ch [m - 1 ] - CH [m - 2 ], p [i] - ch [m - 2 ]) <= 0 ) m - ; ch [m ++] = p [i]; } , Si (n> 1 ) M-- ; retour m; } Double PTS (point p, point A, point B) { /// trouver le point p au segment de ligne AB distance la plus courte IF (A == B) retourner la longueur (p - A); point V1 = B - A , V2 = P - A, V3 = P - B; IF (dCMP (Dot (V1, V2)) < 0 ) retourner la longueur (V2), l'autre IF (dCMP (Dot (V1, V3))> 0 ) retourner la longueur (V3), le else retour FABS (Cross (V1, V2)) / la longueur (V1); } / * distance parallèle au segment ligne A1A2 et B1B2 * / DoubleDS (point A1, le point a2, point b1, point b2) { retour min (PTS (b1, a1, a2), min (PTS (b2, a1, a2), min (PTS (a1, b1, b2), PTS (a2, b1, b2)))); } / * 得到向量A1A2和b1b2的位置关系* / double - Get_angle (point A1, le point a2, b1 point, point b2) { point t = b1 - (b2 - a1); retour Cross (a2 - a1, t - a1); } Doubles Rotating_calipers (Point P [], int n, point Q [], int m) { int POSP = 0 , POSQ = 0 ; représentant (i, 0 , n - 1 ) , si(DCMP (P [i] .y - P [POSP] .y) < 0 ) POSP = i; représentant (i, 0 , m - 1 ) si (DCMP (Q [i] .y - Q [POSQ] .y)> 0 ) POSQ = i; deux tmp ans = 1E99; représentant (i, 0 , n - 1 ) { pendant que (DCMP (tmp = Get_angle (P [POSP], P [(POSP + 1 )% n], Q [POSQ], Q [(POSQ + 1 )% m] )) < 0 ) POSQ = (POSQ + 1 )% m; si (DCMP (tmp) == 0 ) ans= Min (ans, DS (P [POSP], P [(POSP + 1 )% n], Q [POSQ], Q [(POSQ + 1 )% m])); d'autre ans = min (ans, PTS (Q [POSQ], P [POSP], P [(POSP + 1 )% n])); POSP = (POSP + 1 )% n; } Retourner ans; } Point P [N], Q [N], p [N], q [N]; int main () { int n, m; tandis que (scanf ( " % d% d " , et n, m &) && n + m) { rep (i, 0 , n - 1 ) scanf ( "%% lf lf "et p [i] .x, et p [i] .y), représentant (i, 0 , m - 1 ) scanf ( " %% lf lf " , & q [i] .x, et q [i] .y); n = enveloppe convexe (p, n, P); m = enveloppe convexe (q, m, Q); deux ans = min (Rotating_calipers (P, n, Q, m), Rotating_calipers (Q, m , P, n)); printf ( " % .5f \ n " , ans); } retour 0 ; }