#include #include #include #include #include using namespace std; typedef pair Punto; float distanciaAlCuadrado(const Punto & p1, const Punto & p2) { float a = p2.first - p1.first; float b = p2.second - p1.second; return a * a + b * b; } bool compararY(const Punto & p1, const Punto & p2) { return p1.second < p2.second; } float distanciaMinima(const vector & puntosX, const vector & puntosY) { int talla = puntosX.size(); if (talla == 2) return distanciaAlCuadrado(puntosX[0], puntosX[1]); if (talla == 3) return min({distanciaAlCuadrado(puntosX[0], puntosX[1]), distanciaAlCuadrado(puntosX[0], puntosX[2]), distanciaAlCuadrado(puntosX[1], puntosX[2])}); int tallaIzquierda = talla / 2, tallaDerecha = talla - tallaIzquierda; vector izquierdaX(tallaIzquierda), derechaX(tallaDerecha), izquierdaY(tallaIzquierda), derechaY(tallaDerecha); for (int i = 0; i < tallaIzquierda; i++) izquierdaX[i] = puntosX[i]; for (int i = 0; i < tallaDerecha; i++) derechaX[i] = puntosX[i + tallaIzquierda]; for (int i = 0, j = 0, k = 0; i < talla; i++) if (puntosY[i] < derechaX[0]) izquierdaY[j++] = puntosY[i]; else derechaY[k++] = puntosY[i]; float minima = min(distanciaMinima(izquierdaX, izquierdaY), distanciaMinima(derechaX, derechaY)); vector centro; float frontera = izquierdaX[tallaIzquierda - 1].first; for (int i = 0; i < talla; i++) if( abs(frontera - puntosY[i].first) < minima ) centro.push_back(puntosY[i]); for (int i = 0; i < centro.size() - 1; i++) for (int j = i + 1; j < centro.size() && centro[j].second - centro[i].second < minima; j++) minima = min(minima, distanciaAlCuadrado(centro[i], centro[j])); return minima; } float distanciaMinima(const vector & puntos) { // Suponiendo puntos.size() >= 2 vector puntosX(puntos), puntosY(puntos); sort(puntosX.begin(), puntosX.end()); for (int i = 0; i < puntosX.size() - 1; i++) if (puntosX[i] == puntosX[i + 1]) return 0; sort(puntosY.begin(), puntosY.end(), compararY); return sqrt(distanciaMinima(puntosX, puntosY)); } int main () { default_random_engine default_random; uniform_real_distribution generadorAleatorio(-1000.0, 1000.0); vector puntos; for (int talla = 2, tallaMax = 10; tallaMax <= 100000; tallaMax *= 10) for (; talla < tallaMax; talla += tallaMax / 10) { while(puntos.size() < talla) puntos.push_back(Punto(generadorAleatorio(default_random), generadorAleatorio(default_random))); float distancia = distanciaMinima(puntos); cout << talla << "\t" << distancia << endl; } }