M-SOLUTIONS プロコンオープン 2020 A ~ D解説(Python3)
M-SOLUTIONS プロコンオープン 2020の解説です!
当日は都合により参加が出来なかったのですが、バーチャル参加しました!!
結果は4完40分程度でした。本番だと水パフォだったので参加したかった...
(この記事は解法を詳細に説明しているため約15分程度で読めます)
A問題-「Kyu in AtCoder」
問題URL : https://atcoder.jp/contests/m-solutions2020/tasks/m_solutions2020_a
問題概要:
最高レーティングが与えられるので、問題文のルールに従って保有する級を示す数字を出力せよ。
解法1:
愚直に、全ての条件を列挙し実装する方法です。プログラミング初心者の方は条件分岐を書く練習となり良い問題となったでしょう。
回答コード:https://atcoder.jp/contests/m-solutions2020/submissions/15498772
解法2:
実は、今回 求める級をとおくと、
という式が成り立ちます。
(ここでは小数切り捨ての割り算であることに注意して下さい)
よって、この式を出力してもAC(正解)することが出来ます。
回答コード:https://atcoder.jp/contests/m-solutions2020/submissions/15498809
B問題-「Magic 2」
問題URL : https://atcoder.jp/contests/m-solutions2020/tasks/m_solutions2020_b
問題概要:
整数が与えられます。
以下の操作を考えます。
- 個の整数うちいずれか個の整数を選び倍する。
- これを回行う。
回以内の操作(0回でも大丈夫です)で、
が成り立つようにできるかを判定しなさい。
解法:
- 整数に対する操作回数を
- 整数に対する操作回数を
- 整数に対する操作回数を
とすると、
が成り立ついずれかので操作を行うことによりが成り立てばよい。
つまり、
が成り立つ組み合わせが1つでもあればよいということになります。
これは、制約が小さいことから全探索により解くことが出来ます。
回答コード:https://atcoder.jp/contests/m-solutions2020/submissions/15459754
C問題-「Marks」
問題URL : https://atcoder.jp/contests/m-solutions2020/tasks/m_solutions2020_c
問題概要(短縮):
評点が以下のようにつけられる。
- 直近回の期末テストの点数を掛け合わせたもの
(ただし学期までの評点はつけられないものとする)
を満たすそれぞれのについて学期の評点が学期の評点より真に高いかを判定し、その判定結果を出力せよ。
解法:
愚直に回分の評定それぞれ求めようとすると、各計算に回、その計算が回繰り返されるので、計算量はとなり、これは制約を考えると回程度の計算量となるためTLE(実行時間制限超過)となります。
それどころか、の制約に注目するとと言う表記がなされています。
仮に、で、全ての評定がであった場合を考えます。
すると、を回掛けることになります。一般的にコンピューターは多倍長整数の計算が苦手なのでが小さくてもこのような計算をすると時間がかかってしまいます。
ここでPoint。
Point【多倍長整数の計算】コンピューターにとって多倍長整数(とても長い整数)のかけ算は苦手なので、時間が多くかかってしまう。
これは、オーバーフロー(int型の範囲を超える)とは違う意味なので履き違えないようにしましょう。(そもそも、Pythonはint型のオーバーフローが発生しないのでオーバーフローを考えなくても良いのですが...)
では、どのようにして計算量を減らすのでしょう。
分かりやすくするために、学期の評点をとおきましょう。
例えば、入力例1の場合
となります。ここで、もう気づいた人もいると思いますが、それぞれのについては共通項があります。
これを考えると、隣合う2つのについて(以降とおきます)
の最後の項がの最初の項よりも真に大きい時、はより真に大きいということがいえるので
問題文における
学期の評点が学期の評点より真に高い
という条件を満たすことになります。(公式解説を見た方が分かりやすいかも...)
そのため、これは組ある
との関係を調べれば良く、
計算量もとなります。
回答コード:https://atcoder.jp/contests/m-solutions2020/submissions/15459769
D問題-「Road to Millionaire」
問題URL : https://atcoder.jp/contests/m-solutions2020/tasks/m_solutions2020_d
問題概要:
問題文にあるとおりに株をうまく取引したとき、最終的な所持金は最大でいくらになるかを出力せよ。
解法(取引日で行動を変える):
取引日によって行動を変える貪欲法によって解くことが可能です。
(とにかく株を買えばお得になるように行動するということです)
行動パターンは以下の通りです。
- 日目
株を買う、もしくは買わないの2択です。
ここで、(1日目の株価) < (2日目の株価)が成り立っていれば株を買う
成り立っていなければ株を買わない という行動が最適です - 日目
株を持っているか持っていないか・日目の株価との比較で最適な行動がそれぞれ変化します。
株を持っている場合
日目の株価が日目の株価より高い、または同じならば売らない
日目の株価が日目の株価より低いならば売る
という行動が最適です。
株を持っていない場合
日目の株価が日目の株価より高い、または同じならば買う
日目の株価が日目の株価より低いならば買わない
という行動が最適です。 - 日目
株を売るか、株を所有していなければそのまま株を買わない
という行動が最適です。
幸いにもの制約は小さいので、このような複雑な貪欲法のシミュレーションを行うことにより解くことが出来ます。
回答コード:https://atcoder.jp/contests/m-solutions2020/submissions/15467841
以上、M-SOLUTIONS プロコンオープン 2020の解説でした!
公式解説にはこの他にも別の解法もあるので、実装できる人はやってみましょう!!
質問・指摘点などがあればコメントなどでお願いします...!!