|
1 | 1 | package g3401_3500.s3453_separate_squares_i
|
2 | 2 |
|
3 |
| -// #Medium #Array #Binary_Search #2025_02_18_Time_134_ms_(30.30%)_Space_95.92_MB_(93.94%) |
| 3 | +// #Medium #Array #Binary_Search #2025_02_18_Time_57_ms_(100.00%)_Space_102.84_MB_(84.85%) |
4 | 4 |
|
5 | 5 | class Solution {
|
6 |
| - private fun helper(line: Double, squares: Array<IntArray>): Double { |
7 |
| - var aAbove = 0.0 |
8 |
| - var aBelow = 0.0 |
9 |
| - for (square in squares) { |
10 |
| - val y = square[1] |
11 |
| - val l = square[2] |
12 |
| - val total = l.toDouble() * l |
13 |
| - if (line <= y) { |
14 |
| - aAbove += total |
15 |
| - } else if (line >= y + l) { |
16 |
| - aBelow += total |
| 6 | + fun separateSquares(squares: Array<IntArray>): Double { |
| 7 | + val n = squares.size |
| 8 | + val arr = Array(n) { LongArray(3) } |
| 9 | + var total = 0.0 |
| 10 | + var left = Long.MAX_VALUE |
| 11 | + var right = Long.MIN_VALUE |
| 12 | + for (i in 0..n - 1) { |
| 13 | + val y = squares[i][1].toLong() |
| 14 | + val z = squares[i][2].toLong() |
| 15 | + arr[i][0] = y |
| 16 | + arr[i][1] = y + z |
| 17 | + arr[i][2] = z |
| 18 | + total += (z * z).toDouble() |
| 19 | + left = minOf(left, arr[i][0]) |
| 20 | + right = maxOf(right, arr[i][1]) |
| 21 | + } |
| 22 | + while (left < right) { |
| 23 | + val mid = (left + right) / 2 |
| 24 | + var low = 0.0 |
| 25 | + for (a in arr) { |
| 26 | + if (a[0] >= mid) { |
| 27 | + continue |
| 28 | + } else if (a[1] <= mid) { |
| 29 | + low += a[2] * a[2] |
| 30 | + } else { |
| 31 | + low += a[2] * (mid - a[0]) |
| 32 | + } |
| 33 | + } |
| 34 | + if (low + low + 0.00001 >= total) { |
| 35 | + right = mid |
17 | 36 | } else {
|
18 |
| - // The line intersects the square. |
19 |
| - val aboveHeight = (y + l) - line |
20 |
| - val belowHeight = line - y |
21 |
| - aAbove += l * aboveHeight |
22 |
| - aBelow += l * belowHeight |
| 37 | + left = mid + 1 |
23 | 38 | }
|
24 | 39 | }
|
25 |
| - return aAbove - aBelow |
26 |
| - } |
27 |
| - |
28 |
| - fun separateSquares(squares: Array<IntArray>): Double { |
29 |
| - var lo = 0.0 |
30 |
| - var hi = 2 * 1e9 |
31 |
| - for (i in 0..59) { |
32 |
| - val mid = (lo + hi) / 2.0 |
33 |
| - val diff = helper(mid, squares) |
34 |
| - if (diff > 0) { |
35 |
| - lo = mid |
36 |
| - } else { |
37 |
| - hi = mid |
| 40 | + left = right - 1 |
| 41 | + var a1 = 0.0 |
| 42 | + var a2 = 0.0 |
| 43 | + for (a in arr) { |
| 44 | + val x = a[0] |
| 45 | + val y = a[1] |
| 46 | + val z = a[2] |
| 47 | + if (left > x) { |
| 48 | + a1 += (minOf(y, left) - x) * z.toDouble() |
| 49 | + } |
| 50 | + if (right < y) { |
| 51 | + a2 += (y - maxOf(x, right)) * z.toDouble() |
38 | 52 | }
|
39 | 53 | }
|
40 |
| - return hi |
| 54 | + val goal = (total - a1 - a1) / 2 |
| 55 | + val len = total - a1 - a2 |
| 56 | + return right - 1 + (goal / len) |
41 | 57 | }
|
42 | 58 | }
|
0 commit comments