ツバサの備忘録

主に備忘録代わりに精進記録を載せていくつもりです。

AOJ 2931 - 括弧を語る数 / Parentheses Number (RUPC2019 Day3 B)

問題
提出コード

解法

まず、順列pに逆の情報を持たせます。すなわち、
i 番目の開き括弧が j 番目の閉じ括弧に対応しているとき、 数列のi番目の値は j である。
というようにします。
すると、スタックを利用して、次のような操作を行うことで、問題の条件を満たす括弧列を作成することができます。
まず、今見ている配列の添え字をi、次に出現する閉じ括弧がj番目であるとします。

  1. スタックにp_iをプッシュします。と同時に、答えとなる文字列sに"("を追加します。

  2. スタックの一番上と、jを比較します。数字が同じであれば、スタックからその数字を取り出して捨てます。そして、jを1増やして、sに")"を追加します。

  3. 2の操作が行える限り行います。スタックが空になるか、数字が一致しなくなったら1の操作に戻ります。p_{i}をすべてプッシュし終えていたら、全ての操作を終了します。

こうしてできたsが答えとなります。ただし、スタックの中身が空になっていなければ、問題の条件を満たす文字列が無かったことになり、":("を出力することになります。

感想

括弧列といえばスタックを頭の片隅に入れている気がします。
今回も片隅においてはいたのですが、うまい処理を思いつけずにいたので、先輩にヒントをいただきました。
再帰でやろうとしていたので、こっちの方がおそらくシンプルに実装できたと思います。