diff --git a/solution/1800-1899/1870.Minimum Speed to Arrive on Time/README.md b/solution/1800-1899/1870.Minimum Speed to Arrive on Time/README.md index 0d6ddf8f60d6e..b429e2b9e0d9d 100644 --- a/solution/1800-1899/1870.Minimum Speed to Arrive on Time/README.md +++ b/solution/1800-1899/1870.Minimum Speed to Arrive on Time/README.md @@ -83,60 +83,17 @@ tags: ### 方法一:二分查找 -二分枚举速度值,找到满足条件的最小速度。 +我们注意到,如果一个速度值 $v$ 能够使得我们在规定时间内到达,那么对于任意 $v' > v$,我们也一定能在规定时间内到达。这存在着单调性,因此我们可以使用二分查找,找到最小的满足条件的速度值。 -时间复杂度 $O(n\times \log m)$,其中 $n$ 和 $m$ 分别为数组 `dist` 和最大速度值。 +在二分查找之前,我们需要先判断是否有可能在规定时间内到达。如果列车数量大于向上取整的规定时间,那么一定无法在规定时间内到达,直接返回 $-1$。 -以下是二分查找的两个通用模板: +接下来,我们定义二分的左右边界为 $l = 1$, $r = 10^7 + 1$,然后我们每次取中间值 $\text{mid} = \frac{l + r}{2}$,判断是否满足条件。如果满足条件,我们将右边界移动到 $\text{mid}$,否则将左边界移动到 $\text{mid} + 1$。 -模板 1: +问题转化为判断一个速度值 $v$ 是否能够在规定时间内到达。我们可以遍历每一趟列车,计算每一趟列车的运行时间 $t = \frac{d}{v}$,如果是最后一趟列车,我们直接加上 $t$,否则我们向上取整加上 $t$。最后判断总时间是否小于等于规定时间,如果是则说明满足条件。 -```java -boolean check(int x) { -} - -int search(int left, int right) { - while (left < right) { - int mid = (left + right) >> 1; - if (check(mid)) { - right = mid; - } else { - left = mid + 1; - } - } - return left; -} -``` +二分结束后,如果左边界超过了 $10^7$,说明无法在规定时间内到达,返回 $-1$,否则返回左边界。 -模板 2: - -```java -boolean check(int x) { -} - -int search(int left, int right) { - while (left < right) { - int mid = (left + right + 1) >> 1; - if (check(mid)) { - left = mid; - } else { - right = mid - 1; - } - } - return left; -} -``` - -做二分题目时,可以按照以下套路: - -1. 写出循环条件 $left < right$; -1. 循环体内,不妨先写 $mid = \lfloor \frac{left + right}{2} \rfloor$; -1. 根据具体题目,实现 $check()$ 函数(有时很简单的逻辑,可以不定义 $check$),想一下究竟要用 $right = mid$(模板 $1$) 还是 $left = mid$(模板 $2$); -     - 如果 $right = mid$,那么写出 else 语句 $left = mid + 1$,并且不需要更改 mid 的计算,即保持 $mid = \lfloor \frac{left + right}{2} \rfloor$; -     - 如果 $left = mid$,那么写出 else 语句 $right = mid - 1$,并且在 $mid$ 计算时补充 +1,即 $mid = \lfloor \frac{left + right + 1}{2} \rfloor$; -1. 循环结束时,$left$ 与 $right$ 相等。 - -注意,这两个模板的优点是始终保持答案位于二分区间内,二分结束条件对应的值恰好在答案所处的位置。 对于可能无解的情况,只要判断二分结束后的 $left$ 或者 $right$ 是否满足题意即可。 +时间复杂度 $O(n \times \log M)$,其中 $n$ 和 $M$ 分别为列车数量和速度的上界。空间复杂度 $O(1)$。 @@ -145,12 +102,15 @@ int search(int left, int right) { ```python class Solution: def minSpeedOnTime(self, dist: List[int], hour: float) -> int: - def check(speed): - res = 0 + def check(v: int) -> bool: + s = 0 for i, d in enumerate(dist): - res += (d / speed) if i == len(dist) - 1 else math.ceil(d / speed) - return res <= hour + t = d / v + s += t if i == len(dist) - 1 else ceil(t) + return s <= hour + if len(dist) > ceil(hour): + return -1 r = 10**7 + 1 ans = bisect_left(range(1, r), True, key=check) + 1 return -1 if ans == r else ans @@ -161,25 +121,30 @@ class Solution: ```java class Solution { public int minSpeedOnTime(int[] dist, double hour) { - int left = 1, right = (int) 1e7; - while (left < right) { - int mid = (left + right) >> 1; + if (dist.length > Math.ceil(hour)) { + return -1; + } + final int m = (int) 1e7; + int l = 1, r = m + 1; + while (l < r) { + int mid = (l + r) >> 1; if (check(dist, mid, hour)) { - right = mid; + r = mid; } else { - left = mid + 1; + l = mid + 1; } } - return check(dist, left, hour) ? left : -1; + return l > m ? -1 : l; } - private boolean check(int[] dist, int speed, double hour) { - double res = 0; - for (int i = 0; i < dist.length; ++i) { - double cost = dist[i] * 1.0 / speed; - res += (i == dist.length - 1 ? cost : Math.ceil(cost)); + private boolean check(int[] dist, int v, double hour) { + double s = 0; + int n = dist.length; + for (int i = 0; i < n; ++i) { + double t = dist[i] * 1.0 / v; + s += i == n - 1 ? t : Math.ceil(t); } - return res <= hour; + return s <= hour; } } ``` @@ -190,25 +155,29 @@ class Solution { class Solution { public: int minSpeedOnTime(vector& dist, double hour) { - int left = 1, right = 1e7; - while (left < right) { - int mid = (left + right) >> 1; - if (check(dist, mid, hour)) { - right = mid; + if (dist.size() > ceil(hour)) { + return -1; + } + const int m = 1e7; + int l = 1, r = m + 1; + int n = dist.size(); + auto check = [&](int v) { + double s = 0; + for (int i = 0; i < n; ++i) { + double t = dist[i] * 1.0 / v; + s += i == n - 1 ? t : ceil(t); + } + return s <= hour; + }; + while (l < r) { + int mid = (l + r) >> 1; + if (check(mid)) { + r = mid; } else { - left = mid + 1; + l = mid + 1; } } - return check(dist, left, hour) ? left : -1; - } - - bool check(vector& dist, int speed, double hour) { - double res = 0; - for (int i = 0; i < dist.size(); ++i) { - double cost = dist[i] * 1.0 / speed; - res += (i == dist.size() - 1 ? cost : ceil(cost)); - } - return res <= hour; + return l > m ? -1 : l; } }; ``` @@ -217,21 +186,58 @@ public: ```go func minSpeedOnTime(dist []int, hour float64) int { + if float64(len(dist)) > math.Ceil(hour) { + return -1 + } + const m int = 1e7 n := len(dist) - const mx int = 1e7 - x := sort.Search(mx, func(s int) bool { - s++ - var cost float64 - for _, v := range dist[:n-1] { - cost += math.Ceil(float64(v) / float64(s)) + ans := sort.Search(m+1, func(v int) bool { + v++ + s := 0.0 + for i, d := range dist { + t := float64(d) / float64(v) + if i == n-1 { + s += t + } else { + s += math.Ceil(t) + } } - cost += float64(dist[n-1]) / float64(s) - return cost <= hour - }) - if x == mx { + return s <= hour + }) + 1 + if ans > m { return -1 } - return x + 1 + return ans +} +``` + +#### TypeScript + +```ts +function minSpeedOnTime(dist: number[], hour: number): number { + if (dist.length > Math.ceil(hour)) { + return -1; + } + const n = dist.length; + const m = 10 ** 7; + const check = (v: number): boolean => { + let s = 0; + for (let i = 0; i < n; ++i) { + const t = dist[i] / v; + s += i === n - 1 ? t : Math.ceil(t); + } + return s <= hour; + }; + let [l, r] = [1, m + 1]; + while (l < r) { + const mid = (l + r) >> 1; + if (check(mid)) { + r = mid; + } else { + l = mid + 1; + } + } + return l > m ? -1 : l; } ``` @@ -240,35 +246,33 @@ func minSpeedOnTime(dist []int, hour float64) int { ```rust impl Solution { pub fn min_speed_on_time(dist: Vec, hour: f64) -> i32 { + if dist.len() as f64 > hour.ceil() { + return -1; + } + const M: i32 = 10_000_000; + let (mut l, mut r) = (1, M + 1); let n = dist.len(); - - let check = |speed| { - let mut cur = 0.0; - for (i, &d) in dist.iter().enumerate() { - if i == n - 1 { - cur += (d as f64) / (speed as f64); - } else { - cur += ((d as f64) / (speed as f64)).ceil(); - } + let check = |v: i32| -> bool { + let mut s = 0.0; + for i in 0..n { + let t = dist[i] as f64 / v as f64; + s += if i == n - 1 { t } else { t.ceil() }; } - cur <= hour + s <= hour }; - - let mut left = 1; - let mut right = 1e7 as i32; - while left < right { - let mid = left + (right - left) / 2; - if !check(mid) { - left = mid + 1; + while l < r { + let mid = (l + r) / 2; + if check(mid) { + r = mid; } else { - right = mid; + l = mid + 1; } } - - if check(left) { - return left; + if l > M { + -1 + } else { + l } - -1 } } ``` @@ -282,32 +286,30 @@ impl Solution { * @return {number} */ var minSpeedOnTime = function (dist, hour) { - if (dist.length > Math.ceil(hour)) return -1; - let left = 1, - right = 10 ** 7; - while (left < right) { - let mid = (left + right) >> 1; - if (arriveOnTime(dist, mid, hour)) { - right = mid; + if (dist.length > Math.ceil(hour)) { + return -1; + } + const n = dist.length; + const m = 10 ** 7; + const check = v => { + let s = 0; + for (let i = 0; i < n; ++i) { + const t = dist[i] / v; + s += i === n - 1 ? t : Math.ceil(t); + } + return s <= hour; + }; + let [l, r] = [1, m + 1]; + while (l < r) { + const mid = (l + r) >> 1; + if (check(mid)) { + r = mid; } else { - left = mid + 1; + l = mid + 1; } } - return left; + return l > m ? -1 : l; }; - -function arriveOnTime(dist, speed, hour) { - let res = 0.0; - let n = dist.length; - for (let i = 0; i < n; i++) { - let cost = parseFloat(dist[i]) / speed; - if (i != n - 1) { - cost = Math.ceil(cost); - } - res += cost; - } - return res <= hour; -} ``` diff --git a/solution/1800-1899/1870.Minimum Speed to Arrive on Time/README_EN.md b/solution/1800-1899/1870.Minimum Speed to Arrive on Time/README_EN.md index 04815774eaef8..48acea1aa2c99 100644 --- a/solution/1800-1899/1870.Minimum Speed to Arrive on Time/README_EN.md +++ b/solution/1800-1899/1870.Minimum Speed to Arrive on Time/README_EN.md @@ -81,7 +81,19 @@ tags: -### Solution 1 +### Solution 1: Binary Search + +We notice that if a speed value $v$ allows us to arrive within the stipulated time, then for any $v' > v$, we can also definitely arrive within the stipulated time. This exhibits monotonicity, hence we can use binary search to find the smallest speed value that meets the condition. + +Before conducting the binary search, we need to first determine if it is possible to arrive within the stipulated time. If the number of trains is greater than the ceiling of the stipulated time, then it is definitely impossible to arrive within the stipulated time, and we should directly return $-1$. + +Next, we define the left and right boundaries for the binary search as $l = 1$, $r = 10^7 + 1$, and then we take the middle value $\text{mid} = \frac{l + r}{2}$ each time to check if it meets the condition. If it does, we move the right boundary to $\text{mid}$; otherwise, we move the left boundary to $\text{mid} + 1$. + +The problem is transformed into determining whether a speed value $v$ can allow us to arrive within the stipulated time. We can traverse each train trip, calculate the running time of each trip $t = \frac{d}{v}$, if it is the last trip, we directly add $t$; otherwise, we round up and add $t$. Finally, we check if the total time is less than or equal to the stipulated time, if so, it means the condition is met. + +After the binary search ends, if the left boundary exceeds $10^7$, it means we cannot arrive within the stipulated time, and we return $-1$; otherwise, we return the left boundary. + +The time complexity is $O(n \times \log M)$, where $n$ and $M$ are the number of train trips and the upper bound of the speed, respectively. The space complexity is $O(1)$. @@ -90,12 +102,15 @@ tags: ```python class Solution: def minSpeedOnTime(self, dist: List[int], hour: float) -> int: - def check(speed): - res = 0 + def check(v: int) -> bool: + s = 0 for i, d in enumerate(dist): - res += (d / speed) if i == len(dist) - 1 else math.ceil(d / speed) - return res <= hour + t = d / v + s += t if i == len(dist) - 1 else ceil(t) + return s <= hour + if len(dist) > ceil(hour): + return -1 r = 10**7 + 1 ans = bisect_left(range(1, r), True, key=check) + 1 return -1 if ans == r else ans @@ -106,25 +121,30 @@ class Solution: ```java class Solution { public int minSpeedOnTime(int[] dist, double hour) { - int left = 1, right = (int) 1e7; - while (left < right) { - int mid = (left + right) >> 1; + if (dist.length > Math.ceil(hour)) { + return -1; + } + final int m = (int) 1e7; + int l = 1, r = m + 1; + while (l < r) { + int mid = (l + r) >> 1; if (check(dist, mid, hour)) { - right = mid; + r = mid; } else { - left = mid + 1; + l = mid + 1; } } - return check(dist, left, hour) ? left : -1; + return l > m ? -1 : l; } - private boolean check(int[] dist, int speed, double hour) { - double res = 0; - for (int i = 0; i < dist.length; ++i) { - double cost = dist[i] * 1.0 / speed; - res += (i == dist.length - 1 ? cost : Math.ceil(cost)); + private boolean check(int[] dist, int v, double hour) { + double s = 0; + int n = dist.length; + for (int i = 0; i < n; ++i) { + double t = dist[i] * 1.0 / v; + s += i == n - 1 ? t : Math.ceil(t); } - return res <= hour; + return s <= hour; } } ``` @@ -135,25 +155,29 @@ class Solution { class Solution { public: int minSpeedOnTime(vector& dist, double hour) { - int left = 1, right = 1e7; - while (left < right) { - int mid = (left + right) >> 1; - if (check(dist, mid, hour)) { - right = mid; + if (dist.size() > ceil(hour)) { + return -1; + } + const int m = 1e7; + int l = 1, r = m + 1; + int n = dist.size(); + auto check = [&](int v) { + double s = 0; + for (int i = 0; i < n; ++i) { + double t = dist[i] * 1.0 / v; + s += i == n - 1 ? t : ceil(t); + } + return s <= hour; + }; + while (l < r) { + int mid = (l + r) >> 1; + if (check(mid)) { + r = mid; } else { - left = mid + 1; + l = mid + 1; } } - return check(dist, left, hour) ? left : -1; - } - - bool check(vector& dist, int speed, double hour) { - double res = 0; - for (int i = 0; i < dist.size(); ++i) { - double cost = dist[i] * 1.0 / speed; - res += (i == dist.size() - 1 ? cost : ceil(cost)); - } - return res <= hour; + return l > m ? -1 : l; } }; ``` @@ -162,21 +186,58 @@ public: ```go func minSpeedOnTime(dist []int, hour float64) int { + if float64(len(dist)) > math.Ceil(hour) { + return -1 + } + const m int = 1e7 n := len(dist) - const mx int = 1e7 - x := sort.Search(mx, func(s int) bool { - s++ - var cost float64 - for _, v := range dist[:n-1] { - cost += math.Ceil(float64(v) / float64(s)) + ans := sort.Search(m+1, func(v int) bool { + v++ + s := 0.0 + for i, d := range dist { + t := float64(d) / float64(v) + if i == n-1 { + s += t + } else { + s += math.Ceil(t) + } } - cost += float64(dist[n-1]) / float64(s) - return cost <= hour - }) - if x == mx { + return s <= hour + }) + 1 + if ans > m { return -1 } - return x + 1 + return ans +} +``` + +#### TypeScript + +```ts +function minSpeedOnTime(dist: number[], hour: number): number { + if (dist.length > Math.ceil(hour)) { + return -1; + } + const n = dist.length; + const m = 10 ** 7; + const check = (v: number): boolean => { + let s = 0; + for (let i = 0; i < n; ++i) { + const t = dist[i] / v; + s += i === n - 1 ? t : Math.ceil(t); + } + return s <= hour; + }; + let [l, r] = [1, m + 1]; + while (l < r) { + const mid = (l + r) >> 1; + if (check(mid)) { + r = mid; + } else { + l = mid + 1; + } + } + return l > m ? -1 : l; } ``` @@ -185,35 +246,33 @@ func minSpeedOnTime(dist []int, hour float64) int { ```rust impl Solution { pub fn min_speed_on_time(dist: Vec, hour: f64) -> i32 { + if dist.len() as f64 > hour.ceil() { + return -1; + } + const M: i32 = 10_000_000; + let (mut l, mut r) = (1, M + 1); let n = dist.len(); - - let check = |speed| { - let mut cur = 0.0; - for (i, &d) in dist.iter().enumerate() { - if i == n - 1 { - cur += (d as f64) / (speed as f64); - } else { - cur += ((d as f64) / (speed as f64)).ceil(); - } + let check = |v: i32| -> bool { + let mut s = 0.0; + for i in 0..n { + let t = dist[i] as f64 / v as f64; + s += if i == n - 1 { t } else { t.ceil() }; } - cur <= hour + s <= hour }; - - let mut left = 1; - let mut right = 1e7 as i32; - while left < right { - let mid = left + (right - left) / 2; - if !check(mid) { - left = mid + 1; + while l < r { + let mid = (l + r) / 2; + if check(mid) { + r = mid; } else { - right = mid; + l = mid + 1; } } - - if check(left) { - return left; + if l > M { + -1 + } else { + l } - -1 } } ``` @@ -227,32 +286,30 @@ impl Solution { * @return {number} */ var minSpeedOnTime = function (dist, hour) { - if (dist.length > Math.ceil(hour)) return -1; - let left = 1, - right = 10 ** 7; - while (left < right) { - let mid = (left + right) >> 1; - if (arriveOnTime(dist, mid, hour)) { - right = mid; + if (dist.length > Math.ceil(hour)) { + return -1; + } + const n = dist.length; + const m = 10 ** 7; + const check = v => { + let s = 0; + for (let i = 0; i < n; ++i) { + const t = dist[i] / v; + s += i === n - 1 ? t : Math.ceil(t); + } + return s <= hour; + }; + let [l, r] = [1, m + 1]; + while (l < r) { + const mid = (l + r) >> 1; + if (check(mid)) { + r = mid; } else { - left = mid + 1; + l = mid + 1; } } - return left; + return l > m ? -1 : l; }; - -function arriveOnTime(dist, speed, hour) { - let res = 0.0; - let n = dist.length; - for (let i = 0; i < n; i++) { - let cost = parseFloat(dist[i]) / speed; - if (i != n - 1) { - cost = Math.ceil(cost); - } - res += cost; - } - return res <= hour; -} ``` diff --git a/solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.cpp b/solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.cpp index ec80ca0547251..0083993ce4955 100644 --- a/solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.cpp +++ b/solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.cpp @@ -1,24 +1,28 @@ class Solution { public: int minSpeedOnTime(vector& dist, double hour) { - int left = 1, right = 1e7; - while (left < right) { - int mid = (left + right) >> 1; - if (check(dist, mid, hour)) { - right = mid; + if (dist.size() > ceil(hour)) { + return -1; + } + const int m = 1e7; + int l = 1, r = m + 1; + int n = dist.size(); + auto check = [&](int v) { + double s = 0; + for (int i = 0; i < n; ++i) { + double t = dist[i] * 1.0 / v; + s += i == n - 1 ? t : ceil(t); + } + return s <= hour; + }; + while (l < r) { + int mid = (l + r) >> 1; + if (check(mid)) { + r = mid; } else { - left = mid + 1; + l = mid + 1; } } - return check(dist, left, hour) ? left : -1; - } - - bool check(vector& dist, int speed, double hour) { - double res = 0; - for (int i = 0; i < dist.size(); ++i) { - double cost = dist[i] * 1.0 / speed; - res += (i == dist.size() - 1 ? cost : ceil(cost)); - } - return res <= hour; + return l > m ? -1 : l; } -}; \ No newline at end of file +}; diff --git a/solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.go b/solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.go index d1c0d941cc2a2..9f1c04909d5b2 100644 --- a/solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.go +++ b/solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.go @@ -1,17 +1,24 @@ func minSpeedOnTime(dist []int, hour float64) int { + if float64(len(dist)) > math.Ceil(hour) { + return -1 + } + const m int = 1e7 n := len(dist) - const mx int = 1e7 - x := sort.Search(mx, func(s int) bool { - s++ - var cost float64 - for _, v := range dist[:n-1] { - cost += math.Ceil(float64(v) / float64(s)) + ans := sort.Search(m+1, func(v int) bool { + v++ + s := 0.0 + for i, d := range dist { + t := float64(d) / float64(v) + if i == n-1 { + s += t + } else { + s += math.Ceil(t) + } } - cost += float64(dist[n-1]) / float64(s) - return cost <= hour - }) - if x == mx { + return s <= hour + }) + 1 + if ans > m { return -1 } - return x + 1 -} \ No newline at end of file + return ans +} diff --git a/solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.java b/solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.java index 13073b0883c45..ca2f5160693c3 100644 --- a/solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.java +++ b/solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.java @@ -1,23 +1,28 @@ class Solution { public int minSpeedOnTime(int[] dist, double hour) { - int left = 1, right = (int) 1e7; - while (left < right) { - int mid = (left + right) >> 1; + if (dist.length > Math.ceil(hour)) { + return -1; + } + final int m = (int) 1e7; + int l = 1, r = m + 1; + while (l < r) { + int mid = (l + r) >> 1; if (check(dist, mid, hour)) { - right = mid; + r = mid; } else { - left = mid + 1; + l = mid + 1; } } - return check(dist, left, hour) ? left : -1; + return l > m ? -1 : l; } - private boolean check(int[] dist, int speed, double hour) { - double res = 0; - for (int i = 0; i < dist.length; ++i) { - double cost = dist[i] * 1.0 / speed; - res += (i == dist.length - 1 ? cost : Math.ceil(cost)); + private boolean check(int[] dist, int v, double hour) { + double s = 0; + int n = dist.length; + for (int i = 0; i < n; ++i) { + double t = dist[i] * 1.0 / v; + s += i == n - 1 ? t : Math.ceil(t); } - return res <= hour; + return s <= hour; } -} \ No newline at end of file +} diff --git a/solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.js b/solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.js index 80448463da1f6..377a8419bbb8c 100644 --- a/solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.js +++ b/solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.js @@ -4,29 +4,27 @@ * @return {number} */ var minSpeedOnTime = function (dist, hour) { - if (dist.length > Math.ceil(hour)) return -1; - let left = 1, - right = 10 ** 7; - while (left < right) { - let mid = (left + right) >> 1; - if (arriveOnTime(dist, mid, hour)) { - right = mid; + if (dist.length > Math.ceil(hour)) { + return -1; + } + const n = dist.length; + const m = 10 ** 7; + const check = v => { + let s = 0; + for (let i = 0; i < n; ++i) { + const t = dist[i] / v; + s += i === n - 1 ? t : Math.ceil(t); + } + return s <= hour; + }; + let [l, r] = [1, m + 1]; + while (l < r) { + const mid = (l + r) >> 1; + if (check(mid)) { + r = mid; } else { - left = mid + 1; + l = mid + 1; } } - return left; + return l > m ? -1 : l; }; - -function arriveOnTime(dist, speed, hour) { - let res = 0.0; - let n = dist.length; - for (let i = 0; i < n; i++) { - let cost = parseFloat(dist[i]) / speed; - if (i != n - 1) { - cost = Math.ceil(cost); - } - res += cost; - } - return res <= hour; -} diff --git a/solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.py b/solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.py index 3203eb12897e4..697eab7d6d9eb 100644 --- a/solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.py +++ b/solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.py @@ -1,11 +1,14 @@ class Solution: def minSpeedOnTime(self, dist: List[int], hour: float) -> int: - def check(speed): - res = 0 + def check(v: int) -> bool: + s = 0 for i, d in enumerate(dist): - res += (d / speed) if i == len(dist) - 1 else math.ceil(d / speed) - return res <= hour + t = d / v + s += t if i == len(dist) - 1 else ceil(t) + return s <= hour + if len(dist) > ceil(hour): + return -1 r = 10**7 + 1 ans = bisect_left(range(1, r), True, key=check) + 1 return -1 if ans == r else ans diff --git a/solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.rs b/solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.rs index 018def82d7bd1..0f5426eea5131 100644 --- a/solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.rs +++ b/solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.rs @@ -1,33 +1,31 @@ impl Solution { pub fn min_speed_on_time(dist: Vec, hour: f64) -> i32 { + if dist.len() as f64 > hour.ceil() { + return -1; + } + const M: i32 = 10_000_000; + let (mut l, mut r) = (1, M + 1); let n = dist.len(); - - let check = |speed| { - let mut cur = 0.0; - for (i, &d) in dist.iter().enumerate() { - if i == n - 1 { - cur += (d as f64) / (speed as f64); - } else { - cur += ((d as f64) / (speed as f64)).ceil(); - } + let check = |v: i32| -> bool { + let mut s = 0.0; + for i in 0..n { + let t = dist[i] as f64 / v as f64; + s += if i == n - 1 { t } else { t.ceil() }; } - cur <= hour + s <= hour }; - - let mut left = 1; - let mut right = 1e7 as i32; - while left < right { - let mid = left + (right - left) / 2; - if !check(mid) { - left = mid + 1; + while l < r { + let mid = (l + r) / 2; + if check(mid) { + r = mid; } else { - right = mid; + l = mid + 1; } } - - if check(left) { - return left; + if l > M { + -1 + } else { + l } - -1 } } diff --git a/solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.ts b/solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.ts new file mode 100644 index 0000000000000..03752f4c030e5 --- /dev/null +++ b/solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.ts @@ -0,0 +1,25 @@ +function minSpeedOnTime(dist: number[], hour: number): number { + if (dist.length > Math.ceil(hour)) { + return -1; + } + const n = dist.length; + const m = 10 ** 7; + const check = (v: number): boolean => { + let s = 0; + for (let i = 0; i < n; ++i) { + const t = dist[i] / v; + s += i === n - 1 ? t : Math.ceil(t); + } + return s <= hour; + }; + let [l, r] = [1, m + 1]; + while (l < r) { + const mid = (l + r) >> 1; + if (check(mid)) { + r = mid; + } else { + l = mid + 1; + } + } + return l > m ? -1 : l; +}