解いた問題
- ABC052 D - Walk and Teleport
- ABC053 D - Card Eater
- ABC239 E - Subtree K-th Max
- ABC276 E - Round Trip
- ABC177 E - Coprime
- ABC115 D - Christmas
- ABC194 E - Mex Min
ABC052 D - Walk and Teleport
感想 (解答中に考えたこと)
- 貪欲かDP。DPは制約的に無理そうなので貪欲の方針にする。
- 1------2-3-4 みたいな町で B = A + 3くらいの条件で考えてみると、234のまとまりにテレポートした方が良い。また、3にテレポートして 3 -> 2 -> 3(経由) -> 4とすると2 -> 3(経由)分が無駄になるので、一番近い場所にテレポートするのが良い。
- よってとして、で良さそう。
提出コード
ABC053 D - Card Eater
感想 (解答中に考えたこと)
- 何を消すかを管理すれば良い?
- 同じカードの枚数が偶数ならば2枚、奇数ならば1枚残る。
- 操作の対象はカードの枚数をとしてであって、操作1回につき2枚ずつ減るので
- この時の操作の回数は
- 偶数枚あるカードの種類の数をとする。
- が奇数のときは1枚まで減らせるため、残った1枚を最小あるいは最大とできるように3枚を選択すれば良いので、操作回数は。
- が偶数の時は2枚まで減らせる。ここでこの2枚を同時消しできる可能性があるので、偶数枚あるカードのうち最小値および最大値を残すように選択する。に含まれる奇数枚のカードが存在すれば操作回数は。存在しなければ
- 操作回数をとすれば、が残るカードの枚数。
提出コード
ABC239 E - Subtree K-th Max
感想 (解答中に考えたこと)
- の制約がそこまでキツくないので、部分木をで出力できれば十分そう。
- 木はとりあえず
list[set[int]]
で管理し、根からBFSで子 -> 親のパスを消し飛ばしておく。- これは不要で、DFSの引数に親を追加し、親 = 子の場合にcontinueすれば良い。
- DFSで根から探索し、各ノードに上位20件の数字のリストを持たせていく。
- つまり葉であれば
[X[n]]
を返し、そうでなければ子ノードの返り値とX[n]
を合わせて降順ソート & limit = 20で良い
- つまり葉であれば
- あとはで答えが出る。テーブルの構築にはDFSでの構築部分とクエリ部分でかかってると思う(たぶん)。
提出コード
部分木といえばオイラーツアーがあったなと反省……。 atcoder.jp
ABC276 E - Round Trip
感想 (解答中に考えたこと)
- BFSでvisitedがTrueのものがあればYes? しかし戻るパターンを除去するのが面倒くさい。
- だらだら実装してサンプルが合わないので解説を少しだけ読む。色分けかぁ……これは思いつきたい。
- visitedをbooleanではなく数値で管理し、
S
を#
扱いにして4方向にBFSするだけになった。
提出コード
ABC177 E - Coprime
感想 (解答中に考えたこと)
- setwise coprimeは
gcd(*A) == 1
で一発で判定可能。つまりpairwise coprimeの判定が肝になる。 - 当然のことながら全探索は無理。ところで、ってが既約分数なので、共通の素因数を持たないと解釈できそう。
- つまり集合の素因数を全部調べて重複があるかを判定すれば良い。
- エラトステネスの篩をつかってまでの素数を列挙し、素数をkeyとしてkeyが素因数として出てきたかを持つboolをvalueとして持つHashMapを用意する。素因数分解はのものを使う。素因数分解については指数の要素はいらないので、素因数の集合を返すように改造しておく。
- あとは出てきた素因数をHashMapに記録し、既にTrueのものがあれば
pairwise
になる。 - これ計算量でじゃないですか?落ちそう -> ACした。
提出コード
エラトステネスの篩で素数を列挙している途中で、とすることで試し割り(2 ~ まで割る方法)をする必要がないのででできるらしい。天才では???? atcoder.jp
ABC115 D - Christmas
感想 (解答中に考えたこと)
- 明らかに再帰関数の実装を求めていそうな問題。とはいえバーガーの高さとパティの枚数は普通に漸化式を解けばで出る。
- レベルバーガーを
g[n]
、バンズをB
、パティをP
とすればレベルバーガーはBg[n-1]Pg[n-1]B
と書ける。 - レベルバーガーに対して、が下部のレベルバーガーの領域を超えている場合のみその分のパティを加え、その分の高さをから引いていけば求まる。
- レベルバーガーの区切りが良いところから始める必要があるので。真ん中のパティを特別に扱わないとバグる。
- パティが存在する領域よりも高いである場合、レベル0バーガーの探索を終えてもは0よりも大きくなるので、ループの条件に
レベル >= 0
が必要 (1敗)
提出コード
正直上記の説明じゃ何も伝わってないと思う……説明難しい……。 atcoder.jp
ABC194 E - Mex Min
感想 (解答中に考えたこと)
- しゃくとりっぽく、区間をずらした際に出ていく数字・入る数字を管理すれば高速で求められそうじゃない?(根拠なし)
- 使える数字をSortedListで管理し、区間にある数字をHashMapで管理する。区間にある数字について、個数が0になったものがあればSortedListにその数字を追加し、個数が1以上になったものがあればSortedListからdiscardする。
- あとはSortedListの先頭をchminすれば良い。これで計算量はなはず。定数倍の遅さにビビりながらsubmit。