Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update cf-702C #4939

Merged
merged 19 commits into from
Nov 24, 2024
Merged
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 67 additions & 30 deletions solutions/silver/cf-702C.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ author: Nathan Wang, Benjamin Qi, Maggie Liu, Brad Ma, George Pong
**Time Complexity:** $\mathcal{O}(N \log N)$

<LanguageSection>

<CPPSection>

```cpp
Expand All @@ -21,7 +20,7 @@ using namespace std;

// returns the first index in the array that is >= value, or arr.size() if no
// such index exists
int firstAtLeast(const vector<int> &arr, int value) {
int first_at_least(const vector<int> &arr, int value) {
int lo = 0, hi = arr.size();
while (lo < hi) {
int mid = (lo + hi) / 2;
Expand All @@ -48,30 +47,31 @@ int main() {
towers.push_back(tower);
}

int minR = 0;
int min_r = 0;
for (int i = 0; i < n; i++) {
int towerRight = firstAtLeast(towers, cities[i]);
int towerLeft = towerRight - 1;

int minRForThisCity = 2e9;
if (towerRight < m) {
assert(towers[towerRight] >= cities[i]);
minRForThisCity = min(minRForThisCity, towers[towerRight] - cities[i]);
int tower_right = first_at_least(towers, cities[i]);
int tower_left = tower_right - 1;

int min_r_for_this_city = 2e9;
if (tower_right < m) {
assert(towers[tower_right] >= cities[i]);
min_r_for_this_city =
min(min_r_for_this_city, towers[tower_right] - cities[i]);
}
if (towerLeft >= 0) {
assert(towers[towerLeft] <= cities[i]);
minRForThisCity = min(minRForThisCity, cities[i] - towers[towerLeft]);
if (tower_left >= 0) {
assert(towers[tower_left] <= cities[i]);
min_r_for_this_city =
min(min_r_for_this_city, cities[i] - towers[tower_left]);
}

minR = max(minR, minRForThisCity);
min_r = max(min_r, min_r_for_this_city);
}

cout << minR << endl;
cout << min_r << endl;
}
```

</CPPSection>

<JavaSection>

```java
Expand Down Expand Up @@ -137,7 +137,50 @@ public class CellularNetwork {
```

</JavaSection>
<PySection>

```py
"""
returns the first index in the array that is >= value, or len(arr)
if no such index exists
"""
SansPapyrus683 marked this conversation as resolved.
Show resolved Hide resolved


freakin23 marked this conversation as resolved.
Show resolved Hide resolved
def first_at_least(value: int) -> int:
lo = 0
hi = len(towers)
while lo < hi:
mid = (lo + hi) // 2
if towers[mid] > value:
hi = mid
else:
lo = mid + 1

return lo


n, m = map(int, input().split())
cities = list(map(int, input().split()))
towers = list(map(int, input().split()))

min_r = 0
for i in range(n):
tower_right = first_at_least(cities[i])
tower_left = tower_right - 1

min_r_for_this_city = float("inf")
if tower_right < m:
min_r_for_this_city = min(min_r_for_this_city, towers[tower_right] - cities[i])

if tower_left >= 0:
min_r_for_this_city = min(min_r_for_this_city, cities[i] - towers[tower_left])

min_r = max(min_r, min_r_for_this_city)

print(min_r)
```

</PySection>
</LanguageSection>

## Solution 2 - Two Pointers
Expand All @@ -149,7 +192,6 @@ We store two pointers, one for the current city and one for the current tower. W
**Time Complexity:** $\mathcal{O}(N)$

<LanguageSection>

<CPPSection>

```cpp
Expand Down Expand Up @@ -202,7 +244,6 @@ int main() {
```

</CPPSection>

<PySection>

```py
Expand Down Expand Up @@ -242,7 +283,6 @@ print(max_dist)
```

</PySection>

<JavaSection>

```java
Expand Down Expand Up @@ -298,8 +338,8 @@ public class CellularNetwork2 {
// CodeSnip{Kattio}
}
```
</JavaSection>

</JavaSection>
</LanguageSection>

## Solution 3 - Using a Set
Expand All @@ -319,10 +359,9 @@ left of the city. Define $\texttt{dist}$ to be the minimum of the distance to
the tower on the right and the distance to the tower on the left. Then, set $r$
to be the maximum of itself and $\texttt{dist}$.

**Time Complexity:** $\mathcal{O}(N\log N)$
**Time Complexity:** $\mathcal{O}(N \log M)$

<LanguageSection>

<CPPSection>

```cpp
Expand All @@ -346,16 +385,16 @@ int main() {
for (int i = 0; i < n; i++) {
int dist = 2e9 + 1;
// find closest tower to the right of the city
auto closesttower = towers.lower_bound(cities[i]);
if (closesttower != towers.end()) {
auto closest_tower = towers.lower_bound(cities[i]);
if (closest_tower != towers.end()) {
// if a tower is found, update the distance
dist = *closesttower - cities[i];
dist = *closest_tower - cities[i];
}
// find closest tower to the left of the city
if (closesttower != towers.begin()) {
closesttower--;
if (closest_tower != towers.begin()) {
closest_tower--;
// update dist with the minimum of the distances
dist = min(dist, cities[i] - *closesttower);
dist = min(dist, cities[i] - *closest_tower);
}
r = max(r, dist);
}
Expand All @@ -365,7 +404,6 @@ int main() {
```

</CPPSection>

<JavaSection>

```java
Expand Down Expand Up @@ -410,5 +448,4 @@ public class CellularNetwork {
```

</JavaSection>

</LanguageSection>
Loading