結果
| 問題 |
No.67 よくある棒を切る問題 (1)
|
| コンテスト | |
| ユーザー |
codewow1
|
| 提出日時 | 2019-12-27 01:53:57 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 214 ms / 5,000 ms |
| コード長 | 2,189 bytes |
| コンパイル時間 | 378 ms |
| コンパイル使用メモリ | 82,908 KB |
| 実行使用メモリ | 107,912 KB |
| 最終ジャッジ日時 | 2025-03-03 11:30:13 |
| 合計ジャッジ時間 | 6,350 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 30 |
ソースコード
import math
N = int(input())
L = list(map(int, input().split()))
K = int(input())
#### 二分探索 O(logN) ####
## ソート済み配列sorted_arrの中にTrueとFalseの境界が存在
## すべてTrue または すべてFalseもありうる
def binary_search_double(val_min, val_max, type="max"):
# 境目のうちTrue側のindexを返す。すべてTrueまたはFalseのときは-1を返す
# 加えてindex=0の真偽値を返す
# ref : 条件式に用いるための変数
eps = 10e-11
if val_min == 0:
val_min += eps
def absolute_error(val1, val2):
return abs(val1 - val2)
def relative_error(val1, val2):
return 1 - (min(val1, val2) / max(val1, val2))
def chk_func(val):
# 条件を設定する
# 対象となる配列、基準となる配列要素(真ん中)、条件判定に使う基準
sum = 0
for Li in L:
sum += math.floor(Li/val)
return sum >= K
# 配列の一番最初と最後の要素がそれぞれ条件を満たすかどうか
TF_left = chk_func(val_min)
TF_right = chk_func(val_max)
if TF_left == TF_right:
# 両方が条件を満たす(または両方が条件を満たさない)場合は終了
# 2番目の返り値に、両方の値(TrueかFalse)が入る
if type == "max":
return val_max, TF_left
elif type == "min":
return val_min, TF_left
else:
if TF_right:
# 最後の要素がTrueの場合、
ok = val_max # 末尾側をTrueにし、
ng = val_min # 先頭側をFalseにする
else:
# 最初の要素がTrueの場合、
ok = val_min # 先頭側をTrueにし、
ng = val_max # 末尾側をFalseにする
while (absolute_error(ok, ng) > eps and relative_error(ok, ng) > eps): # 境目が確定するまで繰り返す
val_mid = (ok + ng)/2
if chk_func(val_mid):
ok = val_mid
else:
ng = val_mid
# ok : 境目のうち、True側の配列インデックス
# 2番目の引数は途中終了の場合との整合性をとるため。
return ok, True
# import pdb
# pdb.set_trace()
print(binary_search_double(max(L)/K, max(L))[0])
codewow1