結果
| 問題 | No.2594 Mix shake!! |
| コンテスト | |
| ユーザー |
hitonanode
|
| 提出日時 | 2023-12-04 02:44:07 |
| 言語 | Python3 (3.13.1 + numpy 2.2.1 + scipy 1.14.1) |
| 結果 |
AC
|
| 実行時間 | 403 ms / 2,000 ms |
| コード長 | 2,658 bytes |
| コンパイル時間 | 94 ms |
| コンパイル使用メモリ | 13,056 KB |
| 実行使用メモリ | 12,032 KB |
| 最終ジャッジ日時 | 2024-09-27 09:05:54 |
| 合計ジャッジ時間 | 12,822 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 85 |
ソースコード
#!/usr/bin/env python3
# これはちゃんと AC のはず
from fractions import Fraction
def make_convex_slope(A: list[int], B: list[int]) -> list[tuple[int, int]]:
x, y = 0, 0
ret: list[tuple[int, int]] = [(0, 0)]
seq = sorted([(Fraction(b, a), a, b) for a, b in zip(A, B)])
for _, a, b in seq:
x += a
y += b
ret.append((x, y))
return ret
def trajectory_solve(
A: list[int], B: list[int], C: list[int], D: list[int]
) -> tuple[bool, list[tuple[Fraction, Fraction]]]:
assert len(A) == len(B) == len(C) == len(D)
assert sum(A) == sum(C)
assert sum(B) == sum(D)
assert min(A + B + C + D) >= 1
assert max(A + B + C + D) <= 100000000000000000
lo_polyline = make_convex_slope(A, B)
hi_polyline = make_convex_slope(C, D)
for (x0, y0), (x1, y1) in zip(lo_polyline, lo_polyline[1:]):
for x, y in hi_polyline:
if (x1 - x0) * (y - y0) - (y1 - y0) * (x - x0) < 0:
return False, []
assert lo_polyline[0] == hi_polyline[0] == (0, 0)
assert lo_polyline[-1] == hi_polyline[-1] == (sum(A), sum(B))
nx, ny = Fraction(0), Fraction(0)
trajectory: list[tuple[Fraction, Fraction]] = [(nx, ny)]
while (nx, ny) != lo_polyline[-1]:
s = Fraction(1 << 60) # slope
for px, py in hi_polyline:
if px <= nx:
continue
s = min(s, Fraction(py - ny, px - nx))
assert s < Fraction(1 << 60)
next_x = Fraction(sum(A))
for (px, py), (qx, qy) in zip(lo_polyline, lo_polyline[1:]):
s2 = Fraction(qy - py, qx - px)
if s2 <= s:
continue
# y = s * (x - nx) + ny と y = s2 * (x - px) + py の交点
# sx - s nx + ny == s2 x - s2 px + py
# (s - s2) x == s nx - ny - s2 px + py
next_x = min(next_x, (s * nx - ny - s2 * px + py) / (s - s2))
ny += s * (next_x - nx)
nx = next_x
trajectory.append((nx, ny))
ans: bool = False
if len(trajectory) - 1 < len(A):
ans = True
else:
abidx = sorted([(Fraction(B[i], A[i]), i) for i in range(len(A))])
cdidx = sorted([(Fraction(D[i], C[i]), i) for i in range(len(B))])
if [i for _, i in abidx] == [i for _, i in cdidx]:
ans = True
return ans, trajectory
if __name__ == "__main__":
input()
A = list(map(int, input().split()))
B = list(map(int, input().split()))
C = list(map(int, input().split()))
D = list(map(int, input().split()))
ret, trajectory = trajectory_solve(A=A, B=B, C=C, D=D)
print("Yes" if ret else "No")
hitonanode