-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstations.cpp
More file actions
67 lines (48 loc) · 1.42 KB
/
stations.cpp
File metadata and controls
67 lines (48 loc) · 1.42 KB
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
// I wrote this during a practice coding interview.
#include <cmath>
#include <iostream>
#include <set>
using Position = long;
bool isInRange(Position house, Position station, Position radius) {
return std::abs(house - station) <= radius;
}
size_t placeStations(const std::set<Position> &houses, Position radius) {
if (houses.empty())
return 0;
size_t station_count = 1;
auto iter = houses.begin();
Position current_position = *iter++ + radius;
while (iter != houses.end()) {
const Position house_position = *iter++;
if (isInRange(house_position, current_position, radius))
continue;
current_position = house_position + radius;
++station_count;
}
return station_count;
}
Position getRadius(const std::set<Position> &houses, size_t max_stations) {
if (houses.empty())
return 0;
const auto max_radius = static_cast<Position>(std::ceil(static_cast<double>(*houses.rbegin() - *houses.begin())
/ max_stations / 2.0));
Position lower = 0;
Position upper = max_radius;
Position radius = max_radius / 2;
for (;;) {
size_t stations = placeStations(houses, radius);
const Position old_radius = radius;
if (stations > max_stations) {
lower = old_radius;
} else {
upper = old_radius;
}
radius = lower + (upper - lower) / 2;
if (radius == old_radius)
return radius;
}
}
// 1, 2, 7, 10, 15, radius = 2
int main() {
std::cout << getRadius({1, 2, 7, 10, 15, 16, 17, 18, 20, 200}, 3) << '\n';
}