れとろのメモ置場

とあるSEのメモ置場

AtCoder Beginner Contest 284

AtCoder Beginner Contest 284に参加しました。

結果

A,B,C,Dの4問正解でした。 E問題ももう少し時間があれば解けそうな気がした。ぱっと解き方を思いつかなかったから先にF問題解いてみたのが失敗だったな。

A - Sequence of Strings

問題文の通り処理する。

配列に文字列を登録してから逆順に表示すれば良い。
文字列はN個とわかっているのでインデックスをNから1まで順番に減らしていけば良い。

配列の扱い方がわかっているかどうかな問題だと思う。

B - Multi Test Cases

これも問題文の通り処理すれば良い。

具体的には以下の処理をT回繰り返せば良い。

  1. Nを受け取る。
  2. 奇数の数をリセットする。
  3. N個のAを受け取り奇数か偶数かを判定する。
    奇数ならカウントする。
  4. カウントした奇数の数を出力する。

A問題くらいの難易度の問題をT回解くコードを書けば良い。

C - Count Connected Components

グラフが与えられるので連結成分の数を答える問題。

連結成分の数という点でUnion-Findを使って解くことにした。 具体的には、ある頂点同士が辺でつながっているという情報からある頂点をもう一方の頂点のグループに追加していった。
最後に、rootが何種類あるのかをsetを使って数える。 setのサイズ=連結成分の数になるので、これで答えが求められる。

D - Happy New Year 2023

すごく単純に言うと、合成数Nが与えられるから元になる素数を答える問題。

情報として、素数は2種類だけでN = p ^ {2} qとなることがわかっている。

Nは 1 \leq N \leq 9 \times 10 ^ {18} とかなり大きいけど、答えとなる素数うち小さい方は\sqrt[3]{N}以下になる。 (もし小さい方の素数さえも\sqrt[3]{N}より大きいなら、その素数^{2} \times もっと大きい素数 > その素数^{3} \geq Nになるから)
なので\sqrt[3]{N}より小さい素数を洗い出してから順番に割り切れるかどうかを確かめる。
割り切れる素数を見つけられたら同じ素数でもう1度割り切れるかどうかを確認する。割り切れないならN/割り切れる素数 = p^{2}になるのでNを素数で割った後の値の平方根をとる。 割り切れるなら同じ素数でさらに割った答えがqとなる。

計算量を考えても O( \sqrt[3]{N} + TM)くらいになると思うのでTLEしないで解ける。(Mは\sqrt[3]{N}以下の素数の数。Nと比べると十分に小さい値になる。)
1番大きいところで\sqrt[3]{N}以下の素数を探すところだけど、どの値が素数かはNに関わらず一定なのでT個あるテストケースの内最大のNに合わせて素数を列挙しておいて 後はテストケースごとに線形探索で素数を1つ見つければ良い。