HaskellでABCを攻略していく ~ABC003C~
問題はこれ ABC003C
リストと数を入力し、ゴニョゴニョ計算した結果の最大を求める問題ですね。
入力
- 動画講座の総数 : _
- 見ることができる動画の数 : k
- 動画配信者のレートのリスト : rs
出力
達成できる最大レート
実装
0からスタートしてk回自分と動画配信者との平均を取り最大値を求める
ソースコード
import Data.List (sort) main :: IO () main = do [_, k] <- map read . words <$> getLine rs <- map read . words <$> getLine print $ ans rs k ans :: [Double] -> Int -> Double ans rs k = let l = length rs list = drop (l - k) $ sort rs in calc list calc :: [Double] -> Double calc list = foldl (\ a b -> (a + b) / 2) 0.0 list
関数
ans関数
答えを返却するための関数
ans :: [Double] -> Int -> Double ans rs k = let l = length rs list = drop (l - k) $ sort rs in calc list
Double型のリストとInt型の値を受け取り、Doubleで本問題の回答を返却する。 let式ではリストの要素数を表す変数 l と視聴する動画配信者のレートを表すリスト list の二つを作成し、calc関数の結果を返却する。
import Data.List (sort)
でsort関数をimportし、引数のrsを整列する。
drop (l - k) りすと
の形になり、drop関数にて、先頭から(l - k)要素をリストから削除する。
最終的には要素数 k で整列されたリストができる。
calc関数
答えを計算する関数
calc :: [Double] -> Double calc list = foldl (\ a b -> (a + b) / 2) 0.0 list
calc関数は整列したDouble型リストが送られてくる。
(\ a b -> (a + b) / 2)
ラムダ式を使い2値の平均を求めている。以降 f
と表す。
foldl f 0.0 list
では、引数で与えられたリストを初期値0.0で関数fを畳み込んでいる。
リストは昇順になっているため、小さい値から順に関数fに適用される。