再帰関数
次のような問題を考えます。
[問題]
整数 k に対して、レベル k の AB文字列 を次のように定義します。 ・レベル 0 の AB 文字列は "B" です。 ・レベル k の AB 文字列は "A" + (レベル k - 1 の AB 文字列) + "B" + (レベル k - 1 の AB 文字列) + "A" です。 例 : レベル 2 の ABC 文字列は "A" + "ABBBA" + "B" + "ABBBA" + "A" = "AABBBABABBBAA" となります。 レベル k の AB 文字列の x 文字目 までに "B" が何個あるかを求めてください。
[条件]
・レベル k は、1以上 50以下の整数 ・x(何文字目) は、1以上 レベル kのAB文字列の長さ以下の整数
解法・ソースコード
まず レベル k のAB文字列の長さは 2の k 乗 以上になり k ≦ 50 という条件を考慮すると、単純に文字列を生成する方法では処理が終わりません。
そこで 再帰関数 を使った解法を考えてみます。
問題をよく読むと、レベル k の AB文字列は レベル k - 1 の AB文字列によって定義されていることがわかります。
つまり、AB文字列は 1つ前のAB文字列 によって再帰的に定義されています。
レベル k の AB文字列の長さを len_s[k]、レベル k の AB文字列に含まれる文字列”B”の個数を cnt_b[k]とします。
このとき、レベル k の AB文字列を表す文字列の先頭から x文字目 に含まれる 文字列”B”の数 は次のように考えることができます。
- x=1のとき
0個 - x=2 ~ len_s[k-1]+1のとき
ひとつ前の文字列レベルの先頭から、x-1文字列の中に含まれる文字列”B”の個数 - x=len_s[k-1]+2のとき
ひとつ前の文字列レベルの文字列”B”の個数+1 - x=len_s[k-1]+3 ~ 2 * len_s[k-1]+2のとき
ひとつ前の文字列レベルの先頭から、x-len_s[k-1]-2文字の中に含まれる文字列”B”の個数 + cnt_b[k-1] + 1個 - x=2*len_s[k-1]+3のとき
cnt_b[k-1] * 2 + 1個
以上により、レベル k の AB文字列 を レベル k-1 の AB文字列 に関する問題へと帰着することができました。
また、レベル k の AB文字列の長さ(len_s) と 文字列”B”の個数(cnt_b) は以下のように定義できます。
- レベル k の AB文字列の長さ
len_s[k] = len_s[k-1] * 2 + 3 (len_s[0] = 1) - 文字列”B”の個数
cnt_b[k] = cnt_b[k-1] * 2 + 1 (cnt_b[0] = 1)
[Google Colaboratory]
1 | #---------- 入力例 1 --------- |
[実行結果]
4
文字列レベル2の文字列は “AABBBABABBBAA” であり、この文字列の先頭から7文字の中に 文字列”B” が 4個 含まれます。