Isa@Diary

ソフトウェア開発やってます。プログラミングとか、US生活とかについて書きます。

Codeforces 215B Olympic Medal

数式ごにょごにょすればいい。

((r1^2 - r2^2) * PI * p1) / (r2^2 * PI * p2) == A / B
(r1^2 - r2^2) * PI * p1 * B == r2^2 * PI * p2 * A  (両辺分母払う)
r2^2 * (p1 * B + p2 * A) == r1^2 * p1 * B      (両辺/PIと分配してr1,r2を分ける)
r2^2 == (r1^2 * p1 * B) / (p1 * B + p2 * A)
r2 == sqrt((r1^2 * p1 * B) / (p1 * B + p2 * A))

で、これを最大化したいのだからr1は最大のものを、p2は最小のものを拾って
あとは全てのp1についてr2を計算してやればいい。

calc::Double->Double->Double->Double->[Double]->Double
calc _ _ _ _ [] = 0
calc r1 p2 a b (y:ys) = max (sqrt ((r1 * r1 * y * b) / (p2 * a + y * b))) (calc r1 p2 a b ys) 

main = do
     xs <- getLine
     let r1 = foldl max 0 (tail (map (read::String->Double) (words xs)))
     ys <- getLine
     let p1 = tail.map (read::String->Double) $ words ys
     zs <- getLine
     let p2 = foldl min 65535 (tail (map (read::String->Double) (words zs)))
     ab' <- getLine
     let ab = map (read::String->Double) $ words ab'
     putStrLn(show $ calc r1 p2 (ab !! 0) (ab !! 1) p1)

getLineとその後の処理、まとめて1行で書けないものか…