フィボナッチ数列の位置に「O」を含む名前を生成するC++コードの解説
数値 n が与えられたとします。Amal はペットに名前を付けようとしており、あるアルゴリズムに従って名前を決定します。名前の長さは n 文字で、大文字の「O」と小文字の「o」のみで構成されます。アルゴリズムのルールは次のとおりです。名前の i 番目の文字は、i がフィボナッチ数列に含まれる場合は大文字の「O」、それ以外の場合は小文字の「o」となります。名前の文字は 1 から n までの番号が付けられています。
例えば、入力が n = 10 の場合、出力は「OOOoOooOoo」になります。これは、フィボナッチ数列の最初の数値が 1、2、3、5、… であるためです。
解法のアプローチ
この問題を解くために、以下の手順に従います。
- まず、サイズ n の文字列 s を用意し、すべての文字を「o」で初期化します。
- 次に、i と j を 1 で初期化し、i が n 以下である限りループを回します。各反復処理の後で i を j ずつ増加させ、j を i - j に更新します。このテクニックにより、フィボナッチ数列を追加の配列や再帰なしで効率的に生成できます。
- ループ内では、s[i-1] を「O」に置き換えます。
- 最終的に文字列 s を返します。
このアルゴリズムの擬似コードは以下のようになります。
s := a string of size n and filled with 'o's
for initializing i and j from 1, when i <= n, increase i by j and set
j := i-j after each iteration, do
s[i-1] := 'O'
return s.C++での実装例
理解を深めるために、以下の実装例を見てみましょう。
#include <bits/stdc++.h>
using namespace std;
string solve(int n){
string s(n, 'o');
for (int i = 1, j = 1; i <= n; i += j, j = i - j)
s[i - 1] = 'O';
return s;
}
int main(){
int n = 10;
cout << solve(n) << endl;
}入力
10
出力
OOOoOooOoo
コードのポイント
この実装の魅力は、そのシンプルさにあります。フィボナッチ数列を事前に計算して配列に保存する代わりに、2つの変数 i と j を使った巧みな更新処理(i += j と j = i - j)によって、数列を順次生成しながら文字列を直接構築しています。これにより、時間計算量はフィボナッチ数の個数に比例し、O(log n) 程度で処理が完了するため、非常に効率的です。
-
C++で指定されたパワーを持つ部分文字列を効率的に検索する方法
問題概要 この問題では、文字列 str と整数 pow が与えられ、指定されたパワーを持つ部分文字列を見つけることが求められます。 具体的には、パワーの合計が pow と一致する部分文字列を返す必要があります。 文字列のパワーとは、その文字列に含まれる各文字のパワーの総和として定義されます。 各文字のパワーは次のように対応しています:a → 1、b → 2、c → 3 …(アルファベットの出現順に対応) 問題を理解するための例 入力 : string = programming、power = 49出力 : pro 解説 − 部分文字列 pro のパワー:power(p) = 16power
-
【C++】指定されたインデックスのN個のフィボナッチ数のGCDを効率的に求める方法
本記事では、指定された複数のインデックスに対応するN個のフィボナッチ数の最大公約数(GCD)を、C++で効率的に求める方法を解説します。 フィボナッチ数列と問題の概要 まずおさらいとして、フィボナッチ数列は「0, 1, 1, 2, 3, 5, 8, 13, 21, 34, …」のように、直前の2つの項の和によって定義される数列です。インデックスは0から始まるため、0番目の要素は0、1番目の要素は1となります。 例えば、インデックス{2, 3, 4, 5}に対応するフィボナッチ数は{1, 2, 3, 5}であり、これらのGCDは1です。 鍵となる性質:GCD(Fibo(i), Fibo(j))