情報妖精の競プロ日記

AtCoderの問題に対する方針を主に書きます

AtCoder Beginner Contest 104

AtCoder Beginner Contest 104 (ABC104) の解説です。
AtCoder Beginner Contest 104 旧版
AtCoder Beginner Contest 104 beta版

解けた問題だけ解説をしていきますー

要項

AtCoder Beginner Contest 104
rated 1200
8/5(日) 21:00 ~ 22:40 (100分)
100-200-300-400 (4問)
ペナルティ: 5分

方針

全完

A - Rated for Me

問題文にあるように、0 \leq R < 1200ならばABC、1200 \leq R < 2800ならばARC、それ以上ならばAGCを出力すれば良いです。

B - AcCepted

S_iSi番目の文字とします。1番目から始まるものとします。
この時、まずS_1はAです。
更に、S_2からS_{|S|-1}までの間にCが1個あります。
そして、残りは全て小文字です。
この処理を行うには、S_2からS_{|S|-1}までに存在したCの個数を数え、それが1個かつS_2からS_{|S|}までに小文字が|S|-2個存在するか確認すれば良いです。

C - All Green

まず、コンプリートボーナスが存在しない時は高得点の問題から順に解くのが最適です。
では、コンプリートボーナスをどう考えれば良いでしょうか?
今回はDが小さいので、どの得点をコンプリートしたかO(2^D)で決め打ってしまいましょう。
そうすると残りはコンプリートボーナスが無いので解く問題数は上からO(D)で求められるので、全体でO(D2^D)で答えが求められます。

D - We Love ABC

まず、?は忘れてABC数を考えましょう。
そして、これは知っていると有利なのですが、こういう3個の問題では中央の文字、つまりBを決め打つと考えやすいことが多いです。
仮に、ある地点T_jにBがあるとします。
この時、このBを含むABC数はT_jの左側にあるAの個数をx、右側にあるCの個数をyとしてxyになります。
つまり、Bの位置を決め打つとO(1)でABC数が求められるので、全体でO(|S|)で答えが導出できます。
では、?も加えて実際に何個になるか考えます。
まず、Bを決め打った時、左のAと右のCから取ると残りの?は全て任意の文字にできるので、?の個数を左側z_1、右側z_2としてxy3^{z_1+z_2}になります。
左の?と右のCから取ると、z_1y3^{z_1+z_2-1}となりますね。反対側も同様です。
よって、答えが求まりました。
ここで、3^zに関して毎回計算すると時間が足りないので、予め3^{10^5}まで途中でmodを取りながら計算して配列にでも入れておきましょう。(3^z \mod 10^9+7 = 3^{z-1} \cdot 3 \mod 10^9 + 7なので3^0から順に求める)
また、左のAの個数、右のCの個数なども累積和という方法を用いて予め計算しておかないと計算時間が足りなくなります。

結果

oooo 4完(1000点) 1:31-6:41-30:19-72:38(2WA) / 82:38
134位

感想

C問題は自分の苦手な全探索系でしたが、なんとかACできて良かったです。
D問題に関しては中央を固定する発想は典型的(例:ABC077_C)なので、ここで覚えてしまいましょう!