Pagini recente » Cod sursa (job #2679989) | Cod sursa (job #432769) | Cod sursa (job #129047) | Cod sursa (job #1432543) | Cod sursa (job #2072442)
#include <fstream>
#include <cmath>
#include <vector>
#include <algorithm>
#include <cmath>
#include <limits>
using namespace std;
ifstream in ("cmap.in");
ofstream out ("cmap.out");
struct punct
{
int x;
int y;
};
int sortare_x(punct a, punct b)
{
return a.x < b.x;
}
int sortare_y(punct a, punct b)
{
return a.y < b.y;
}
int citire(vector<punct> &v, vector <punct> &vx, vector<punct> &vy)
{
int n;
int aux_x;
int aux_y;
punct aux;
in >> n;
for (int i = 0; i < n; ++i)
{
in >> aux_x;
in >> aux_y;
aux.x = aux_x;
aux.y = aux_y;
v.push_back(aux);
vx.push_back(aux);
vy.push_back(aux);
}
sort(vx.begin(), vx.end(), sortare_x);
sort(vy.begin(), vy.end(), sortare_y);
}
int afisare_vector(std::vector<punct> v)
{
for (auto it : v)
{
out << it.x << " " << it.y << endl;
}
return 1;
}
float distanta_euclidiana(punct a, punct b)
{
float distanta;
distanta = sqrt( (a.x - b.x)*(a.x-b.x) + (a.y - b.y)*(a.y - b.y));
return distanta;
}
float distanta_minima_aux(vector <punct> aux, int naux, float d)
{
float min = d; /// distanta minima este presupusa initial ca fiind cea minima gasita in una din partile stangi sau drepti a vectorului
vector <punct> :: iterator it;
vector <punct> :: iterator it1;
for (it = aux.begin(); it != aux.end(); it++)
{
for (it1 = it + 1; it1 != aux.end(); it1++)
{
if ( (*it1).y - (*it).y < min )/// verificam daca cele doua puncte selectate au diferenta coordonatelor y mai mica decat d minima
{
if (distanta_euclidiana(*it, *it1) < min) /// daca distanta celor doua puncte e mai mica decat minimul actual
{
min = distanta_euclidiana(*it, *it1); ///actualizam minimul
}
}
}
}
return min;
}
float gaseste_dist_minima(vector <punct> vx, vector <punct> vy, int n)
{
float d;
float dmin = 100;
vector <punct> :: iterator it;
vector <punct> :: iterator it1;
if (n <= 3) /// daca sunt mai putin de 3 puncte, folosim algoritmul banal de gasire a distantei
{
for (it = vx.begin(); it != vx.end(); it++)
{
for (it1 = it + 1; it1 != vx.end(); it1++) /// parcurgem fiecare element cu fiecare element si calculam distanta minima
{
d = distanta_euclidiana(*it, *it1);
if (d < dmin)
{
dmin = d;
}
}
}
return dmin;
}
int mij = n / 2;
punct punct_median = vx.at(mij);
vector <punct> vy_left; /// vector sortat dupa y in care punem elementele din partea stanga a medianei vectorului
vector <punct> vy_right; /// vector sortat dupa y in care punem elementele din partea dreapta a medianei vectorului
for (auto it : vy)
{
if (it.x <= punct_median.x) /// daca punctul e in partea stanga
{
vy_left.push_back(it); /// inseram in vectorul stang
}
else
{
vy_right.push_back(it); /// daca nu, in cel drept
}
}
float distanta_left = gaseste_dist_minima(vx, vy_left, mij); /// calculam recursiv cea mai mica distanta dintre doua puncte in partea stanga
vector<punct> vx_right (&vx[mij], &vx[n]); /// vx_right este doar partea dreapta copiata din vectorul vx pe care o trimit in functia de mai jos
float distanta_right = gaseste_dist_minima(vx_right, vy_right, n - mij); /// calculam recursiv cea mai mica distanta dintre doua puncte in partea dreapta
d = min(distanta_left, distanta_right); /// luam distanta minima
vector <punct> aux; /// vectorul aux va contine elementele de o parte si de alta care au distanta (de la coorodnatele x) < d gasita minima
for (auto it : vy)
{
if (abs(it.x - punct_median.x) < d)
{
aux.push_back(it);
}
}
int naux = aux.size();
return min(d, distanta_minima_aux(aux, naux, d)); /// la final, afisez minimul dintre distanta minima gasita in cele 2 parti si cea pe care o voi gasi in elementele de o parte si de alta a vectorului
}
int main()
{
vector <punct> v; /// vectorul initial
vector <punct> vx; /// vectorul initial sortat dupa x
vector <punct> vy; /// vectorul initial sortat dupa y
citire(v, vx, vy);
int lungime = v.size();
//afisare_vector(v);
out<<gaseste_dist_minima(vx,vy,lungime);
return 0;
}