#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <float.h>
#include <assert.h>
#define EPS 0.000001
typedef struct Punct{
long int x;
long int y;
}Punct;
int compare_x(const void *a, const void *b) {
Punct *punctA = (Punct *)a;
Punct *punctB = (Punct *)b;
return (int)(punctA->x - punctB->x);
}
int compare_y(const void *a, const void *b) {
Punct *punctA = (Punct *)a;
Punct *punctB = (Punct *)b;
return (int)(punctA->y - punctB->y);
}
double distance(Punct p1, Punct p2)
{
return sqrt((double)((p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y)));
}
double minim(double x, double y)
{
if (x < y) return x;
else return y;
}
float modul(float x)
{
if (x >= 0) return x;
return -x;
}
double fff(Punct *p, int mij, int st, int dr, double dist)
{
float dreapta = (float)(p[mij].x + p[mij+1].x) / 2;
// dreapta - dist, dreapta + dist
if(modul(dreapta - (float)p[mij].x) > dist || modul((float)p[mij].x - dreapta) > dist)
return DBL_MAX;
Punct *ups = (Punct *)malloc(0 * sizeof(Punct));
int k = 0;
if(st <= mij && mij <= dr)
if(modul((float)p[mij].x - dreapta) < dist) {
ups = realloc(ups, (k + 1) * sizeof(Punct));
ups[k++] = p[mij];
}
if(st <= mij+1 && mij+1 <= dr)
if(modul((float)p[mij+1].x - dreapta) < dist) {
ups = realloc(ups, (k + 1) * sizeof(Punct));
ups[k++] = p[mij + 1];
}
if(st <= mij-1 && mij-1 <= dr){
int i = mij-1;
while(modul(dreapta - (float)p[i].x) < dist){
ups = realloc(ups, (k + 1) * sizeof(Punct));
ups[k++] = p[i--];
if(st > i || i > dr)
break;
}
}
if(st <= mij+2 && mij+2 <= dr) {
int j = mij+2;
while (modul((float) p[j].x - dreapta) < dist) {
ups = realloc(ups, (k + 1) * sizeof(Punct));
ups[k++] = p[j++];
if (st > j || j > dr)
break;
}
}
qsort(ups, k, sizeof(Punct), compare_y);
int a, b;
for(a = 0; a < k-1; a++)
for(b = a+1; b <= a+7 && b < k; b++)
if(a != b && distance(ups[a], ups[b]) < dist)
dist = distance(ups[a], ups[b]);
free(ups);
if(dist == 0)
puts("Err! dist == 0");
return dist;
}
double cmap(Punct *p, int st, int dr)
{
if(dr - st > 2){
int mij = (st + dr)/2;
double dist = minim(cmap(p, st, mij), cmap(p, mij+1, dr));
return minim(dist, fff(p, mij, st, dr, dist));
}
int i, j;
double min_distance = DBL_MAX;
for(i = st; i <= dr-1; i++)
for(j = st+1; j <=dr; j++)
if(i != j && distance(p[i], p[j]) < min_distance)
min_distance = distance(p[i], p[j]);
if(min_distance == 0)
puts("Err! min dist == 0");
return min_distance;
}
double test(char *fname)
{
FILE *f;
f = fopen(fname, "r");
int n, i;
fscanf(f, "%d", &n);
// Crearea vectorului
Punct *p = (Punct *)malloc(n * sizeof(Punct));
// Citirea vectorului
for (i = 0; i < n; i++){
fscanf(f, "%ld", &p[i].x);
fscanf(f, "%ld", &p[i].y);
}
qsort(p, n, sizeof(Punct), compare_x);
double r = cmap(p, 0, n-1);
free(p);
fclose(f);
return r;
}
int main()
{
FILE *fout;
fout = fopen("cmap.out", "w");
double rezultat;
rezultat = test("cmap.in");
fprintf(fout, "%f", rezultat);
fclose(fout);
/*
assert(modul(test("/Users/cristinasavin/CLionProjects/untitled1/test1.txt") - 348638.547165) < EPS);
assert(modul(test("/Users/cristinasavin/CLionProjects/untitled1/test2.txt") - 1510277.801566) < EPS);
assert(modul(test("/Users/cristinasavin/CLionProjects/untitled1/test3.txt") - 84526.067600) < EPS);
assert(modul(test("/Users/cristinasavin/CLionProjects/untitled1/test4.txt") - 4924.201458) < EPS);
assert(modul(test("/Users/cristinasavin/CLionProjects/untitled1/test5.txt") - 67373.170476) < EPS);
assert(modul(test("/Users/cristinasavin/CLionProjects/untitled1/test6.txt") - 21721.562398) < EPS);
assert(modul(test("/Users/cristinasavin/CLionProjects/untitled1/test7.txt") - 6480.748414) < EPS);
assert(modul(test("/Users/cristinasavin/CLionProjects/untitled1/test8.txt") - 14195.229621) < EPS);
assert(modul(test("/Users/cristinasavin/CLionProjects/untitled1/test9.txt") - 7754.601473) < EPS);
assert(modul(test("/Users/cristinasavin/CLionProjects/untitled1/test10.txt") - 9597.368181) < EPS);
puts("SUCCES");
*/
return 0;
}