れとろのメモ置場

とあるSEのメモ置場

トヨタ自動車プログラミングコンテスト2023#8(AtCoder Beginner Contest 333)

トヨタ自動車プログラミングコンテスト2023#8(AtCoder Beginner Contest 333)に参加しました。

結果

A,B,C問題の3問ACでした。

D問題が惜しいとこまで解けたけどACはできなかった。
前々からちょっと精進不足な気がしてたから、今やってる資格の勉強が終わったら 競プロの精進をしばらくしようと思った。

A - Three Threes

1桁の整数がN入力されるので、 NをN回出力する問題。

ループと標準出力ができればACできる問題。

B - Pentagon

正五角形に2本対角線が引かれるから、対角線の長さが等しいかどうかを答える問題。

頂点はA,B,C,D,Eの5つなのでcharとして扱えば辺何本分離れているのかが簡単に求められる。

対角線の一方の頂点がAにあるとすると、 もう一方の頂点がB,Eのどちらかにある場合、 C,Dのどちらかにある場合の2通りがあり得る。

なので、上記で求めた辺何本分離れているかからこの2通りのどちらのパターンなのかを判断して、 2本ある頂点両方が同じパターンかどうかを確認して答えを出力した。

C - Repunit Trio

すべての桁の数が1である整数(レピュニット)3つの和の整数のうち小さいものからN番目の数を答える問題。

どうすれば効率よく答えられるか考えてみたけど、結局333通り列挙して、 N番目に小さいものを答えて解いた。

色々考えてみて、規則性とかを確認するために試しにある程度の数を出力してみたら、300個くらいがあっという間に出力できた。 なので、Nの最大値である333個以上を予め求めておいて、その中からN番目に小さい数を出力することにした。

D - Erase Leaves

もう少しというところまでは解けたけどACできなかった問題。

木が与えられるので葉を順番に取り除いて言って1を取り除くまでにいくつの頂点を削除するかを答える問題。

頂点1を根とする木として考えて、頂点1に隣接する頂点の下にいくつ頂点があるのかが分かれば答えられそうだなと思った。 だからまずは、部分木の頂点数を求める方法を考えることにした。

木構造なのでUnion-Find木を使えば良いかなと思ったけど、 標準的なUnion-Findなら頂点の親はわかるけど子はわからないし、子がわからないということは、任意の頂点にぶら下がっている頂点の数も変わらないということなのでちょっと使いづらいなあとなった。

次に思ったのが深さ優先探索で、葉から順番に自分の子孫の数を数えていけば任意の頂点にぶら下がっている頂点の数が簡単に求められるそうだなとなったので、深さ優先探索を使うことにした。

コンテスト中だと、頂点1を根とする木の任意の頂点の子孫の数を一通り求めることができた。 あとは、頂点1の隣接している各頂点の子孫の数(部分木の要素数)をもとにどうにかすれば答えを求められるとは思ったけど、ちょっと考察が足りなくてうまく数が合わなかった。

解説を斜め読みするとNから部分木の要素数の最大値を引いたものが答えになるらしい。