結果
| 問題 |
No.2594 Mix shake!!
|
| コンテスト | |
| ユーザー |
Sumitacchan
|
| 提出日時 | 2023-12-17 15:47:16 |
| 言語 | Python3 (3.13.1 + numpy 2.2.1 + scipy 1.14.1) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 4,294 bytes |
| コンパイル時間 | 181 ms |
| コンパイル使用メモリ | 13,056 KB |
| 実行使用メモリ | 12,672 KB |
| 最終ジャッジ日時 | 2024-09-27 09:06:30 |
| 合計ジャッジ時間 | 7,439 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 WA * 2 |
| other | AC * 80 WA * 5 |
ソースコード
# -*- coding: utf-8 -*-
"""
濃度の大小が同じであればn-1本の判定はいらないというのを考慮していない
"""
from fractions import Fraction
import sys
from typing import Sequence
def validate(n: int, a: Sequence[int], b: Sequence[int], c: Sequence[int], d: Sequence[int]) -> None:
MIN_N = 2
MAX_N = 50
MIN_VAL = 1
MAX_VAL = 10 ** 17
assert MIN_N <= n <= MAX_N
for seq in [a, b, c, d]:
assert len(seq) == n
assert all(MIN_VAL <= x <= MAX_VAL for x in seq)
assert sum(a) == sum(c)
assert sum(b) == sum(d)
def output_ans(ans: bool) -> None:
if ans:
print("Yes")
else:
print("No")
sys.exit()
def compute_slope(n: int, a: Sequence[int], b: Sequence[int]) -> tuple[list[tuple[int, int]], list[int]]:
"""b[i]/a[i] の昇順に加算した (aの累積和,bの累積和) と、昇順のソートした際の index の列を返す"""
p: list[int] = sorted(list(range(n)), key=lambda i: Fraction(b[i], a[i]))
slope: list[tuple[int, int]] = [(0, 0)]
for i in p:
x, y = slope[-1]
slope.append((x + a[i], y + b[i]))
return slope, p
def evaluate(slope: Sequence[tuple[int, int]], x: int) -> Fraction:
for i in range(len(slope) - 1):
if slope[i][0] <= x <= slope[i + 1][0]:
x0, y0 = slope[i]
x1, y1 = slope[i + 1]
return Fraction((x1 - x) * y0 + (x - x0) * y1, x1 - x0)
assert False
if __name__ == "__main__":
n: int = int(input())
a: list[int] = list(map(int, input().split()))
b: list[int] = list(map(int, input().split()))
c: list[int] = list(map(int, input().split()))
d: list[int] = list(map(int, input().split()))
validate(n, a, b, c, d)
ls, lp = compute_slope(n, a, b)
us, up = compute_slope(n, c, d)
assert ls[0] == us[0] == (0, 0)
assert len(ls) == len(us) == n + 1 and ls[n] == us[n]
# us が ls の上側にない場合は不可
for x, y in us[1: n]:
if y < evaluate(ls, x):
output_ans(False)
for x, y in ls[1: n]:
if y > evaluate(us, x):
output_ans(False)
# 以下、us は ls の上側にあることが保証されている
# 濃度の順番が同じならば可能
#if lp == up:
# output_ans(True)
# 2つの容器で濃度が同一であるような中間状態が必要
# us を越さないように ls 上の点を貪欲に通りながら n-1 本以下の線分で左下から右上に行けるか判定する
x_c: Fraction = Fraction(0, 1)
y_c: Fraction = Fraction(0, 1)
for i in range(n - 1):
# us の上側を通らずに (x_c, y_c) から ls[i+2] まで引ければ OK
x_t, y_t = ls[i + 2]
# us の上側を通らないような傾きを求める
# us と ls の上下関係は保証されているので、us における開区間 (x_c, x_t) 内の点のみを項考慮すればよい
# (この区間の点と外側の点を結んだ線分によって初めて条件が破れる、といったケースはない)
slopes: list[Fraction] = [Fraction(y - y_c, x - x_c) for x, y in us if x_c < x < x_t]
if len(slopes) == 0:
# 邪魔者はいない
output_ans(True)
# x=x_t まで進めればよいという条件のもとでの最大の傾き
max_slope: Fraction = min(slopes)
# c -> t への傾き
slope_ct: Fraction = Fraction(y_t - y_c, x_t - x_c)
if slope_ct <= max_slope:
# (x_t, y_t) まで進める
output_ans(True)
else:
# (x_t, y_t) までは進めないので可能な限り進む
# その点は線分 ls[i+1] - ls[i+2] 上にある
x_u, y_u = ls[i + 1]
# (x_c, y_c) を通る傾き max_slope の直線と上記線分の交点を求める
slope_ut: Fraction = Fraction(y_t - y_u, x_t - x_u)
x_next = Fraction(max_slope * x_c - slope_ut * x_u - y_c + y_u, max_slope - slope_ut)
y_next = max_slope * (x_next - x_c) + y_c
assert x_u <= x_next < x_t
assert y_next == slope_ut * (x_next - x_u) + y_u
x_c, y_c = x_next, y_next
output_ans(False)
Sumitacchan