Cod sursa(job #2066662)

Utilizator InsomniaccTrocan Eduard-Valentin Insomniacc Data 15 noiembrie 2017 11:35:59
Problema Cele mai apropiate puncte din plan Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.06 kb
// ClosestTwoPoints.cpp : Defines the entry point for the console application.
//

//#include "stdafx.h"
#include <iostream>
//#include <vector>
#include <algorithm>
#include <fstream>
#include <math.h>

using namespace std;

struct Point
{
	int x, y;
};

void interclas(Point *X, int st, int mij, int dr)
{
	Point  aux[100005];
	int k = 0;
	int i = st, j = mij + 1;
	while (i <= mij && j <= dr)
	{
		if (X[i].y < X[j].y)
			aux[k++] = X[i++];
		else
			aux[k++] = X[j++];
	}

	if(i>mij)
		while (j<=dr)
			aux[k++] = X[j++];
	else
		while (i <= mij)
			aux[k++] = X[j++];

	for (size_t i = 0; i < k; i++)
	{
		X[st + i] = aux[i];
	}

}

bool increasingX(const Point a, const Point b)
{
	return a.x < b.x;
}

bool increasingY(const Point a, const Point b)
{
	return a.y < b.y;
}

double mind(const double a, const double b)
{
	return (a < b) ? a : b;
}

double distance(const Point a, const Point b)
{
	return (sqrt((b.x - a.x)*(b.x - a.x) + (b.y - a.y)*(b.y - a.y)));
}

double closestDistance(int st, int dr, Point *X,Point &first,Point &second)
{
	if (dr - st < 4)
	{
		sort(X + st, X + dr, increasingY);		// Se sorteaza elementele crescator dupa ordonata

		int mind = 1000000000;								// Distanta minima dintre doua puncte din X[st...dr]
		int pos1 = -1, pos2 = -1;
		for (int i = 0; i < dr; i++)
		{
			for (int j = i+1; j <= dr; j++)
			{
				int distaux = distance(X[i], X[j]);
				if (distaux < mind)
				{
					mind = distaux;
					pos1 = i;
					pos2 = j;
				}

			}
		}
		first = X[pos1];
		second = X[pos2];
		return mind;	
	}
	else
	{
		// Divide
		int mij = (st + dr) / 2;

		Point f1, f2, f3, s1, s2, s3;
		
		double d1 = closestDistance(st, mij, X, f1, s1);
		double d2 = closestDistance(mij + 1, dr, X, f2, s2);
		double delta = mind(d1, d2);
		double d3 = 1000000000;

		// Ne uitam in banda

		for (size_t i = st; i < dr; i++)
		{
			if (abs(X[i].x - mij) > delta)
				continue;

			for (size_t j = i + 1; j <= dr; j++)
			{
				if (abs(X[j].x - mij) > delta)
					continue;

				double aux = distance(X[i], X[j]);
				if (aux < d3)
				{
					f3 = X[i];
					s3 = X[j];
					d3 = aux;
				}
				else if (aux > delta)
					break;
			}
		}

		// Stabilim care e distanta minima si punctele ce o formeaza
		if (mind(delta, d3) == delta)
		{
			if (delta == d1)
			{
				first = f1;
				second = s1;
				return d1;
			}
			else
			{
				first = f2;
				second = s2;
				return d2;
			}
		}
		else
		{
			first = f3;
			second = s3;
			return d3;
		}
	}

}

int main()
{
	int n;
	ifstream fin("cmap.in");
	ofstream fout("cmap.out");
	fin >> n;
	Point *arr_x = new Point[n];
	
	int xx, yy;

	for (int i = 0; i < n; i++)
	{
		fin >> xx >> yy;
		arr_x[i].x = xx;
		arr_x[i].y = yy;
	}
	
	fin.close();

	sort(arr_x, arr_x + n, increasingX);
	
	Point p1, p2;

	fout << closestDistance(0, n - 1, arr_x, p1, p2) << endl;
	//cout << "(" << p1.x << "," << p1.y << ") , " << "(" << p2.x << "," << p2.y << ")\n";
	delete[] arr_x;
    return 0;
}