Cod sursa(job #2667866)

Utilizator AcuasPopescu Nicolae-Aurelian Acuas Data 3 noiembrie 2020 23:57:31
Problema Cele mai apropiate puncte din plan Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.88 kb
// Transpiled from GO
#include <iostream>
#include <fstream>
#include <tuple>
#include <cmath>
#include <climits>
#include <algorithm>

typedef struct {
  int X;
  int Y;
} point;

std::tuple<int, point *> readFile(std::string filepath) {
  int n;
  point *points;
  std::ifstream fin(filepath);

  fin >> n;
  points = new point[n + 1];
  int x, y;
  for (int i = 0; i < n; i++) {
    fin >> x >> y;
    points[i].X = x;
    points[i].Y = y;
  }

  return std::make_tuple(n, points);
}

float distance(point p1, point p2) {
  return sqrt(pow(p1.X - p2.X, 2) + pow(p1.Y - p2.Y, 2));
}

float bruteForce(point points[], int start, int stop) {
  float min = INT64_MAX;

  for (auto i = start; i < stop; i++)   {
    for (auto j = i + 1; j < stop; j++)     {
      auto d = distance(points[i], points[j]);
      if ( min > d ) {
        min = d;
      }
    }
  }
  return min;
}

int compareY(point p1, point p2) {
  return p1.Y - p2.Y;
}

float divide(point points[], int start, int stop, int n) {

  if ( stop - start <= 3 ) {
    return bruteForce(points, start, stop);
  }
  auto mid = (start + stop) / 2;

  float dl, dr;
  dl = divide(points, start, mid, n);
  dr = divide(points, mid + 1, stop, n);
  float d = std::min(dl, dr);
  point * strip = new point[n + 1];
  int j = 0;
  for (int i = 0; i < n; i++)   {

    if ( points[i].X- points[mid].X < d ) {
      strip[j] = points[i]; j++;
    }
  }
  auto m = j;
  std::sort(strip, strip + j, compareY);

  for (int i = 0; i < m; i++)   {

    for (auto j = i + 1; j < m && strip[j].Y - strip[i].Y < d; j++)     {

      if ( distance(strip[i], strip[j]) < d ) {
        d = distance(strip[i], strip[j]);
      }
    }
  }

  delete []strip;
  return d;
}

int main(int argc, char **argv) {
  auto tuple = readFile("cmap.in");
  auto points = std::get<1>(tuple);
  auto n = std::get<0>(tuple);
  std::ofstream fout("cmap.out");
  fout << divide(points, 0, n, n);
}