Pagini recente » Cod sursa (job #2921967) | Cod sursa (job #2813427) | Cod sursa (job #2599014) | Cod sursa (job #1385727) | Cod sursa (job #2066330)
#include <iostream>
#include <vector>
#include <algorithm>
#include <fstream>
#include <cmath>
using namespace std;
struct Punct{
int x;
int y;
};
// Distanta pentru R^2
double returnDist(Punct& P1,Punct& P2)
{
return sqrt((P2.x - P1.x)*(P2.x - P1.x) + (P2.y - P1.y)*(P2.y - P1.y));
}
// Functia de comparare pentru vectorul ordonat dupa x
int compByXCoord(Punct& A1, Punct& A2)
{
if(A1.x == A2.x)
return A1.y < A2.y;
return A1.x < A2.x;
}
// Functia de comparare pentru vectorul ordonat dupa y
int compByYCoord(Punct& A1, Punct& A2)
{
if(A1.y == A2.y)
return A1.x < A2.x;
return A1.y < A2.y;
}
// Pentru 4 puncte, calculam direct cea mai mica distanta
double bruteForce4Points(int n, vector<Punct> &Puncte)
{
int i, j;
double minDist = 1000000;
for(i = 0; i < n - 1; i++)
for(j = i + 1; j < n; j++)
if(minDist > returnDist(Puncte[i],Puncte[j]))
minDist = returnDist(Puncte[i],Puncte[j]);
return minDist;
}
// Comparare de float-uri, se putea folosi min
float minF(float x, float y)
{
if(x > y)
return y;
return x;
}
/*
La acest pas consideram toate punctele ordonate dupa Y si comparam
cu distanga minima pana la acest pas. Distanga se actualizeaza cand gaseste
o pereche a carei distanta este mai mica decat cea actuala.
*/
float searchVerticalSection(vector<Punct> &vertSect, float distance)
{
float min = distance;
for (int i = 0; i < vertSect.size() - 1; i ++)
for (int j = i + 1; j < vertSect.size() &&
(vertSect[j].y - vertSect[i].y) < min; j++ )
if ( returnDist(vertSect[i], vertSect[j]) < min)
min = returnDist(vertSect[i], vertSect[j]);
return min;
}
float closPointsDivide(vector<Punct> &PuncteX,vector<Punct> &PuncteY, int dim)
{
if (dim <= 4)
return bruteForce4Points(dim, PuncteX);
int middle = dim / 2;
vector<Punct> leftY;
vector<Punct> rightY;
int i;
for(i = 0 ; i < dim; i++)
{
if(PuncteY[i].x <= PuncteX[dim/2].x)
leftY.push_back(PuncteY[i]);
else
rightY.push_back(PuncteY[i]);
}
float minDistLeft = closPointsDivide(PuncteX,leftY, middle);
float minDistRight = closPointsDivide(PuncteX,rightY, dim - middle);
float dist = min(minDistLeft, minDistRight);
vector<Punct> vertSect;
int j = 0;
for(int i = 0 ; i < dim; i++)
{
if(abs(PuncteY[i].x - PuncteX[middle].x) < dist )
vertSect.push_back(PuncteY[i]);
}
return min(dist, searchVerticalSection(vertSect,dist) );
}
int main()
{
vector<Punct> pointsX;
vector<Punct> pointsY;
ifstream fileRead("cmap.in");
ofstream fileWrite("cmap.out");
int nrPoints, i;
Punct P;
fileRead >> nrPoints;
for(i = 0 ; i < nrPoints; i++)
{
fileRead >> P.x;
fileRead >> P.y;
pointsX.push_back(P);
pointsY.push_back(P);
}
sort(pointsX.begin(),pointsX.end(),compByXCoord);
sort(pointsY.begin(),pointsY.end(),compByYCoord);
fileWrite << closPointsDivide(pointsX, pointsY, nrPoints);
return 0;
}