071 C - Linear Approximation¶
- created: 2022-12-02
- ご意見・ご要望はissue・プルリク用のGitHubまで
- 競技プログラミングのためのF#入門
- GitHub上の対応ディレクトリ
- 公式ページ, ABC 077 C - Snuke Festival
- 公式解説, PDF
解説¶
公式解説通り入力Aaをシフトした配列をBaとします. 解説の便宜のためBaをソートした配列をCaとしましょう.
公式解説通りに実装すれば問題ありません. 他の人のコードを見ていると中央値の扱いにぶれがあるようです. 単にBa.[N/2]だけとしているコードもあれば, 偶奇でわけたコードもあります.
ちなみに私はさらに違う処理にしました. 選ぶべきbが整数でなければならないため, Nが奇数のときはCa.[N/2], Nが偶数のときはCa.[N/2]とCa.{N/2-1}を中央値の候補としています. もちろんNが偶数のときは二つの値を計算して小さい方を取ります.
どう書くとすっきりするかは人によるものの, 私は中央値の候補を配列にして処理しました. 具体的には次のように中央値の候補を作っています.
1 2 | |
最終的な悲しさの最小値は中央値の配列Maから次のように計算しています.
1 | |
よほど複雑な処理をかませる場合は適切な対処が必要ですが, Array.map f |> Array.sumはArray.sumByで書くとすっきりします.
私がはまり倒したため念のため書いておきます. 次のように書くとMaの値を取ってしまい正しい悲しさの最小値が得られません.
1 | |
おまけ¶
次の二つのコードの結果が面白いです.
- https://atcoder.jp/contests/abc102/submissions/2783376
- 言語: F# (Mono 4.0)
- 実行時間: 207 ms
- メモリ: 35328 KB
1 2 3 4 | |
- https://atcoder.jp/contests/abc102/submissions/2783237
- 言語: F# (Mono 4.0)
- 実行時間: 207 ms
- メモリ: 31932 KB
1 2 3 4 | |
違うのは最後の和を取る部分でsumByなのかfoldかです. 実行時間は変わらないものの消費メモリが一割違います. 少なくともMono 4.0でメモリ効率を考えるならfoldの方がよいようです.
そしてさらに私の提出コードも見てみましょう.
- https://atcoder.jp/contests/abc102/submissions/36920080
- 言語: F# (.NET Core 3.1.201)
- 実行時間: 154 ms
- メモリ: 49092 KB
1 2 3 4 5 6 7 8 | |
偶数項のとき和を二回取っているため明らかにこちらの方が遅いはずですが, Mono 4.0よりも高速です. Mono 4.0のリリースが2015年, .NET core 3.1.201のリリースが2021年で後者の方が新しいため, 処理系の高速化のおかげでしょう.