-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathClosest.java
119 lines (99 loc) · 3.58 KB
/
Closest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;
public class Closest {
static class Point implements Comparable<Point> {
long x, y;
public Point(long x, long y) {
this.x = x;
this.y = y;
}
@Override
public int compareTo(Point o) {
return o.y == y ? Long.signum(x - o.x) : Long.signum(y - o.y);
}
}
static double minimalDistance(int[] x, int y[]) {
List<Point> points = new ArrayList<>();
for (int i = 0; i < x.length; i++) {
points.add(new Point(x[i], y[i]));
}
return Math.sqrt(getMinDistance(points));
}
static long getMinDistance(List<Point> points) {
if (points.size() <= 4) {
long min = Long.MAX_VALUE;
for (int i = 0; i < points.size(); i++) {
for (int j = 0; j < points.size(); j++) {
if (i != j) {
long distance = distance(points.get(i), points.get(j));
if (distance < min) {
min = distance;
}
}
}
}
return min;
} else {
Collections.sort(points , (o1, o2) -> (int) (o1.x - o2.x));
int midIndex = points.size() / 2;
long midX = points.get(midIndex).x;
long leftDistance = getMinDistance(points.subList(0, midIndex));
long rightDistance = getMinDistance(points.subList(midIndex, points.size()));
long minDistance = Math.min(leftDistance, rightDistance);
List<Point> stripPoints = new ArrayList<>();
for (Point point : points) {
if ((point.x - midX) * (point.x - midX) < minDistance) {
stripPoints.add(point);
}
}
Collections.sort(stripPoints, (o1, o2) -> (int) (o1.y - o2.y));
for (int i = 0; i < stripPoints.size(); i++) {
for (int j = 1; j < Math.min(i + 8, stripPoints.size()); j++) {
if (i == j) {
continue;
}
minDistance = Math.min(minDistance, distance(stripPoints.get(i), stripPoints.get(j)));
}
}
return minDistance;
}
}
static long distance(Point first, Point second) {
return (first.x - second.x) * (first.x - second.x) + (first.y - second.y) * (first.y - second.y);
}
public static void main(String[] args) throws Exception {
reader = new BufferedReader(new InputStreamReader(System.in));
writer = new PrintWriter(System.out);
int n = nextInt();
int[] x = new int[n];
int[] y = new int[n];
for (int i = 0; i < n; i++) {
x[i] = nextInt();
y[i] = nextInt();
}
System.out.println(String.format("%.4f", minimalDistance(x, y)));
writer.close();
}
static BufferedReader reader;
static PrintWriter writer;
static StringTokenizer tok = new StringTokenizer("");
static String next() {
while (!tok.hasMoreTokens()) {
String w = null;
try {
w = reader.readLine();
} catch (Exception e) {
e.printStackTrace();
}
if (w == null)
return null;
tok = new StringTokenizer(w);
}
return tok.nextToken();
}
static int nextInt() {
return Integer.parseInt(next());
}
}