Cod sursa(job #2283522)

Utilizator SirStevensIonut Morosan SirStevens Data 15 noiembrie 2018 16:38:10
Problema Cele mai apropiate puncte din plan Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.88 kb
// cmap.cpp : Defines the entry point for the console application.
//

#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <climits>
#include <iomanip>

using namespace std;

struct point {
	int x, y;
};

ifstream in("cmap.in");
ofstream out("cmap.out");

vector <point> points, Y;
int n;

void read() {
	in >> n;
	point A;
	for (int i = 1; i <= n; i++) {
		in >> A.x >> A.y;
		points.push_back(A);
		Y.push_back(A);
	}
	
}

bool operator < (const point& A, const point& B) {
	if (A.x == B.x) {
		if (A.y < B.y) {
			return true;
		}
		return false;
	}
	else if (A.x < B.x) {
		return true;
	}
	return false;
}

bool cmp (const point& A, const point& B) {
	if (A.y == B.y){
		if (A.x < B.x) {
			return true;
		}
		return false;
	}
	else if (A.y < B.y) {
		return true;
	}
	return false;
}


double computeDistance(const point& A, const point& B) {

	return sqrt(pow(A.x - B.x, 2) + pow(A.y - B.y, 2));
	
}

double minim(double d1, double d2) {
	if (d1 < d2) {
		return d1;
	}
	return d2;
}


double minnn(double d1, double d2, double d3) {
	double d4 = minim(d1, d2);
	return minim(d3, d4);
}


double minn(const vector <point>& arr,int left,int right) {
	double d1, d2 = computeDistance(arr[left], arr[left+1]), d3;
	for (int i = left; i < right - 1; i++) {
		for (int j = i + 1; j < right; j++) {
			d1 = computeDistance(arr[i], arr[j]);
			if (d1 < d2) {
				d2 = d1;
			}
		}
		
	}
	return d2;
	
}

void printValues(const vector <point>& arr) {
	for (auto x : arr) {
		cout << x.x << " " << x.y << '\n';
	}
}

double divide(int left, int right, const vector <point>& Yy) {
	vector <point> SY, DY, LY;
	double d = 0, d1 = 0, d2 = 0, d3 = 0, d4 = 0;
	if (right - left + 1 < 4) {
		d =  minn(points, left, right);
		cout << "D: " << d << '\n';
	}
	else {
		
		int mij = left + (right - left) / 2;
		cout << mij << " ";
		for (int i = left; i < right - left + 1; i++) {
			if (Yy[i].x <= points[mij].x) {
				SY.push_back(Yy[i]);
			}
			else {
				DY.push_back(Yy[i]);
			}
		}
		cout << "SY:\n";
		printValues(SY); cout << "DY:\n";
		printValues(DY);

		d1 = divide(left, mij, SY);
		d2 = divide(mij + 1, right, DY);
		d = minim(d1, d2);
		cout << "d: " << d << '\n';
		for (int i = left; i < right - left + 1; i++) {
			if (abs(Yy[i].x - points[mij].x) <= d) {
				LY.push_back(Yy[i]);
			}
			
		}
		d3 = d;
		for (int i = 0; i < LY.size(); i++) {
			int j = i+1;
			while (d4 <= d && j < LY.size()) {
				d4 = computeDistance(LY[j], LY[i]);
				if (d4 < d3) {
					d3 = d4;
				}
				j++;
			}
		}
		cout << d3 << " ";
		d = minim(d, d3);
		
	}
	return d;
}

int main()
{
	read();
	sort(points.begin(), points.end());
	sort(Y.begin(), Y.end(), cmp);
	
	out << fixed << setprecision(6) << divide(0,n-1, Y);
    return 0;
}