AtCoderコンテスト452の復習:五節句判定、端のマス目、骨の文字列、部分列の数え上げ
本記事は、プログラミングコンテスト「AtCoder Beginner Contest 452 (ABC452)」に参加した際の、AからDまでの各問題(Gothec, Draw Frame, Fishbones, No-Subsequence Substring)の復習と解答の備忘録である。記事では、単に提出したコードや解法を提示するだけでなく、コンテスト中に気づいた計算量の課題や、より効率的なアプローチの必要性についても深く考察している点が特徴的だ。
**A問題(Gothec)**では、五節句(1/7, 3/3, 5/5, 7/7, 9/9)に該当するかどうかを判定する問題であり、提出コードではタプルに含まれるかどうかの単純な集合比較(`if (M,D) in [...]`)を用いて効率的に解いている。これは、与えられた5つの固定ペアとの比較が本質的な解法であることを示している。
**B問題(Draw Frame)**は、H×Wのマス目における「端のマス」を特定し、そのマス目を出力する問題である。端のマスとは、辺で隣接するマスが3個以下であるマスと定義されており、提出コードでは、行または列の境界(`i == 0 or i == H-1 or j == 0 or j == W-1`)にあるマスをすべて「端」として判定し、`#`でマークしている。これは、端の定義を境界条件に落とし込むことで解決している。
**C問題(Fishbones)**は、N本の肋骨と1本の脊椎に書く文字列の条件を満たす組み合わせを問うもので、特に「脊椎に書く文字列が特定のS_jであるか」を判定することが目的である。解法としては、各骨(肋骨i)について、脊椎のi文字目に対応する文字が、与えられたM個の候補文字列S_jのどの位置に現れるかを事前に集合(set)として収集する前処理を行う。その後、各S_jが条件を満たすか(つまり、全ての骨の対応文字が、それぞれの骨の候補文字集合に含まれるか)をO(N)で判定している。
**D問題(No-Subsequence Substring)**は、与えられた文字列Sの空でない部分文字列のうち、別の文字列Tを部分列として含まないものの個数を数える高度な問題である。記事では、この問題に対し、尺取り法(Sliding Window)が有効であるという考察を述べている。また、提出コードの計算量分析においては、当初の実装が最悪計算量O(|S|^2)となり、時間制限超過(TLE)のリスクがあったことを自己分析しており、競技プログラミングにおける計算量意識の重要性を強調している。
背景
本記事は、プログラミングコンテスト(AtCoder)の特定の回(ABC452)に参加した際の、各問題の解法と考察をまとめた技術的な備忘録である。プログラミングコンテストは、与えられた制約と問題文に基づき、効率的かつ正確なアルゴリズムを設計・実装する能力が求められる。特に、計算量の最適化や、問題の定義を数学的・論理的に分解する思考プロセスが重要となる。
重要用語解説
- 五節句: 日本の伝統的な五つの節句(1/7, 3/3, 5/5, 7/7, 9/9)を指す。この問題では、特定の月日を判定するための固定のパターンとして利用されている。
- 部分列: 元の文字列から要素を削除し、残った要素を元の順序を保って並べた文字列のこと。連続している必要はなく、順序のみが保たれる。
- 尺取り法: 配列や文字列の部分集合を扱う際、ウィンドウ(窓)のサイズを動的に調整しながら、特定の条件を満たす範囲を効率的に探索するアルゴリズム手法。計算量を削減するのに役立つ。
今後の影響
本記事の考察は、単なる解答の記録に留まらず、計算量分析やアルゴリズムの選択肢を比較検討するプロセスを共有している点で価値が高い。特にD問題での自己批判的な分析は、読者に対して「なぜその解法が最適なのか」という深い思考の重要性を伝えるものであり、競技プログラミング学習者にとって非常に有益な教材となる。今後の展開としては、より高度なデータ構造やアルゴリズム(例:動的計画法、Aho-Corasickなど)の適用例が期待される。