AtCoder Beginner Contest 188参加記(~D問題)
100-200-300-0(2)-0(1)-0で0ペナ3完600点。
A - Three-Point Shot
とのうち小さい方にを足して比較すると良い。もともとどちらが小さかったかを工夫して持つ必要がある。自分は、必ずとなるように適切にswapしてから問題を解いた。こうすると、もともと小さかった方は必ずである、といえる。
計算量は、。
B - Orthogonality
ベクトルとか内積とか、その辺の言葉を知らなくても問題文に定義が書いてあるのでそれをやるだけ。ただし、判定すべき式の左辺に「」が含まれているので、その辺の処理を工夫する必要がある。総和記号を使って書くと、
の真偽を調べればよい。これは、for文などで実装できる。
足し算や掛け算が出てきたときは、数値のオーバーフローに気を付ける(最大値を考える)。今回の場合、最大値はなので、32bitのint型でも収まる。優しい…(伏線)
計算量は、。
C - ABC Tournament
問題文が難しいシリーズ。要するに番号の小さい順に人ずつマッチさせて戦わせ、勝ったほうだけ残せということ(最後の人だけは負けた方を出力しなければならないが、勝った方の逆を出力するという解釈をすればよい)。これを愚直にシミュレーションしたときの計算量を考える。
回戦目では、ペアが試合を行う。一方が勝ってもう一方が負けるので、回戦目に出場する人数は回戦目のとなる。このとき、シミュレーションするために必要なメモリへの参照回数を計算すると
となる。よって、シミュレーションにかかる計算量はであるので、シミュレーションするだけで時間内に答えが得られる。
ちなみに、公式解説の解法2には「選手の集合を前半と後半で2つに分けたとき、一番レートが高い選手と逆の集合にいる選手のうち一番レートが高い選手が答え」と書いてあった。トーナメント表を実際に書いてみると理解できる。こちらも、計算量はと変わらないが、実装はかなり楽である。
D - Snuke Prime
問題文に明記されていないが、制約より日目から日目まで考えればよい(無限ではない)。
また、それぞれの日に関して、個あるサービスのうちどれを使うかはすでに決められていて、選べるのは「利用するすべてのサービスの利用料を普通に支払うか」「すぬけプライムで支払うか」の2択である。この選択は日ごとに独立で、最終的な支払金額を最小化したいので、この2択のうち安い方を貪欲に選べばよい。利用するすべてのサービスの利用料を普通に支払った場合の金額は、いもす法を使って効率的に求められる。
ただし1日ずつ考えていると時間が足りない。与えられる情報は高々個であることから、座標圧縮を用いることで計算量をに落とすことができる。ただし、オーバーフローに注意する(「日数×サービス数×利用料」の最大値がとなってしまう)。どちらの支払い方法でも、支払う日数は変わらないので、1日当たりの支払い金額で比較してから日数を掛ければよい。オーバーフローに気付かず、2WA。
計算量は、ではなく、座標圧縮するときにソートしているので!!!
E - Peddler
町を頂点、道を辺としたグラフで考えると良さそう。あとはわからん。
F - +1-1x2
AGCで見た
感想
オーバーフローには気を付けよう!