3匹の猫

みみねこの競プロ精進メモ

AtCoder Beginner Contest 174の感想

100-200-300-400-500-0で0ペナ5完1500点。

A - Air Conditioner

X30以上かどうかで条件分岐したいので、if文を用いて実装する。計算量はO(1)

B - Distance

N個ある点それぞれについて、「原点からの距離がD以下か?」という質問に答える。原点からの距離がD以下であるような点がいくつあるかを記憶する変数を一つ作ると実装しやすい。今回のA問題のような判定をN回繰り返すイメージ。
計算量はO(N)

C - Repsept

説明のため、問題文で与えられた7,77, 777, \dots というような数列をA7i個続く数をA_iとする。このときAの第n項はA_nである。
数列Aについて、第i項の数から第i+1項の数へ遷移する方法を考える。これは、

  • A_i10倍して
  • それに7を足す

とすれば良いことがわかる。「7\times 10^{i}を足す」とも解釈できるが、上記の方法は変数iに寄らず一意に表現できるので何かと都合が良い。
さて、今回はA_iKの倍数かどうか知りたいが、初項から順番にKで割って行って割り切れるかどうか見る方法をとると、途中でA_iの値がオーバーフローしてしまう可能性がある(Pythonなどでも計算速度が非常に遅くなりTLEする可能性が高い)。ここで、今回は「A_iKで割った余り」がいくつなのかわかれば十分であるので、先ほどの遷移式に

  • Kで割った余りをとる

という操作を追加する。この操作を追加しても正しい値が求まることは剰余算の性質よりわかる(わからない場合は検索してみてください)。
あとは、Kで割った余りが0となるようなA_iが存在しないとき、第何項まで見れば良いのかという問題がある。ところで、先ほどの遷移方法を見ると、A_iA_jをそれぞれKで割った時の余りが等しければ、A_{i+1}A_{j+1}は等しくなることがわかる(ここで「変数に寄らず一意に表現」した恩恵が来る)。よって、あるA_iについて計算した余りが今までに登場していたところで探索を打ち切ればよい。もっと言えば、鳩ノ巣原理より、「A_iKで割った余り」を鳩、「0以上K未満の整数」を鳩ノ巣と見れば、高々第K項までみれば良いことがわかる。
計算量はO(K)

D - Alter Altar

「石を2個選び、それらを入れ替える」という操作は、「石を1個選び、石の色を変える」という操作を2回行ったのと同値なので、できれば石を入れ替える操作を優先して行いたい。最小手数を考えることは一度置いておく。石を入れ替える操作のみで、文字列の中でWRという連続部分文字列が存在しないようにするためには、WRという連続部分文字列を見つけたらそれをRWに置換すればよい。この操作を繰り返すと、最終的にRRR...WWWという文字列に落ち着くことがわかる。逆に、この形式の文字列は問題の条件を満たす。
よって、文字列中のRの個数をRとすると、先頭からR文字目までの中でWという文字はいくつあるかを数えれば、それがそのまま答えとなる(そのWを後半のRと入れ替える操作を行えばよい)。計算量はO(N)

E - Logs

長さA_iの丸太に対して、切った後の長さがそれぞれL以下となるように切るのに必要な切る回数の最小値は(A_i-1)\div Lで求められる。もしLが固定されているなら、N本の丸太全てに対して上記の計算をすることで丸太の長さをL以下にするために必要な切る回数の最小値がわかる。あとはL1以上\max (A_i)の範囲で二分探索して解を求めればよい。計算量はO(N\log \max (A_i))

F - Range Set Query

解法はあっていたが実装で躓いてしまった。詳しいことは後日追記します。ネム

5完までのスピードは速かったが、問題の難易度が全体的に易しめだったせいかパフォはそこまで高くなかった。