A14 - Four Boxes¶
- created: 2022-12-29 thu
- ご意見・ご要望はissue・プルリク用のGitHubまで
- 競技プログラミングのためのF#入門
- GitHub上の対応ディレクトリ
- 公式ページ
- 要点: アルゴリズム
入出力¶
1 2 3 4 5 6 | |
方針¶
全て正の数に対する状況下で和を考える前提ではK以下の要素だけ考えればよいと言ったところで, データによっては全探索が必要です. もちろん単純な計算ではO(N^4)で全く間に合いません. 今回はN <= 1000であるためO(N^3)程度まで計算量を減らす必要があります.
そこで豪快な手に打って出ます. まとめ方は何でも構いませんが, 例えばAaとBa, CaとDaに対してそれぞれ和を取ってまとめて要素がN^2個ある配列を二つ作り, 一方に対しては全探索, 他方に対しては二分探索して計算量を減らします. これで計算量がN^2 * log N程度にまで落とせます.
解説¶
前処理¶
ここでは和を取ってまとめた配列を二つ作ります. 二分探索用のソートが必要です. さらに全ての要素は1以上であるため, K以上の項を見る必要はないためそれもフィルターして外しましょう. つまり次のような量を用意します.
1 2 3 4 | |
どちらか一方だけソートすれば十分です. ここではデバッグしやすいように両方ソートしました. 処理速度を求めるなら余計な処理は削りましょう.
ここでフィルター処理の結果, どちらかの配列が空になっている可能性があります. 全ての要素が1以上である前提下で既に二項の和でKを越えている以上, どちらかの配列が空なら問答無用でNoです.
大枠¶
今回のデータの範囲では上記前処理の上で全探索してもそれほど時間は変わりませんでしたが, 命令型言語でのwhileループのように見つかり次第すぐに打ち切るべく今回は再帰で書きます. 処理のメインは次のように書けます.
1 2 3 4 5 6 | |
あとは二分探索を書けば終わりです.
二分探索の実装¶
これはもはや定型処理です.
1 2 3 | |
この二分探索に対して再帰関数を正確に書くと次のようになります.
1 2 3 4 5 | |