diverta 2019 Programming Contest C - AB Substrings
解法
まず、それぞれの文字列の中に含まれるAB
の個数を調べます。これは、文字列をどのように連結しても、個数が変化することはないので、そのまま答えに加算されます。
では、文字列の連結によってあらたに増えるAB
の個数を調べます。
文字列を連結したときに、新たにAB
を増やすには、
...A
という文字列と、B...
という文字列を、この順に連結する必要があり、このときに1つだけ増えます。
ということで、3種類の文字列の個数をカウントします。それは、
B...A
のように、B
で始まりA
で終わる文字列X...A
のように、B
以外の文字で始まりA
で終わる文字列B...X
のように、B
で始まりA
以外の文字で終わる文字列
です。 それぞれ、とします。
さて、それぞれのパターンをどのように使えばいいか考えてみます。
B...
の文字列と、...A
の文字列は、1対1で対応するので、パターン1の文字列たちは、1つの文字列にまとめてしまっても問題ありません(A
で終わる文字列と、B
で始まる文字列の、個数の差に影響はありません)。
ので、B...AB...AB...A
のような、おっきな文字列に置き換え、を答えに追加します。もしならこの操作はいりません。
次に、パターン1,2,3のうちどの文字列を優先して使用するべきか考えてみます。
すると、パターン2,3を先に利用してしまうと、パターン1の文字列1つではAB
を作成することができなくなってしまいますが、先にパターン1の文字列にパターン2,3の文字列を組み合わせてあげることで、パターン1の文字列を無駄なく使用することができます。その後に、残ったパターン2とパターン3の文字列を1つずつ使用して順番に組み合わせていけばよいです。です。
ということで、
文字列中にはじめから存在している
AB
の個数をカウントするパターン1~3の文字列の個数をカウントし、とする
(のとき)を答えに追加し、とする
(のとき)が1以上ならば、それぞれから値を1減らし、答えのカウントをその分増やす
を追加する
感想
ツメが甘いのでバグをとりきるのに時間がかかりました。
焦りは禁物ですね。