n番目のフィボナッチ数が10の倍数かどうかを効率的に判定する方法
ここでは、n番目のフィボナッチ数が10の倍数かどうかを、数列を実際に計算することなく効率的に判定する方法を紹介します。
例として、フィボナッチ数列を {0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987} とします。このとき、15番目(0から数えて)の項である 610 は10で割り切れます。つまり、n が15の倍数であれば判定結果は true になります。
素朴なアプローチとその課題
最も単純な方法は、指定された項までフィボナッチ数を順に生成し、その値が10で割り切れるかを確認することです。しかし、この方法は項の位置が大きくなると計算コストが膨大になり、巨大な整数の演算も必要になるため、実用的な解法とは言えません。
規則性に着目した効率的なアプローチ
フィボナッチ数列には、2や5で割り切れる項が一定の周期で現れるという美しい規則性があります。
2の倍数になる項:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987
2で割り切れる項は、3項ごとに出現します。
5の倍数になる項:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987
5で割り切れる項は、5項ごとに出現します。
3と5の最小公倍数(LCM)は15です。したがって、15番目ごとのフィボナッチ数(0番目・15番目・30番目…)は必ず10の倍数になることが分かります。逆に言えば、n が15で割り切れるかどうかを確認するだけで、n番目のフィボナッチ数が10の倍数かどうかを定数時間 O(1) で判定できるのです。
アルゴリズム
fiboDivTen(term)
開始
もし term が 15 で割り切れるならば
true を返す
終了
false を返す
終了
C++による実装例
#include<iostream>
using namespace std;
bool fiboDivTen(int term) {
if(term % 15 == 0){
return true;
}
return false;
}
int main() {
int term = 45;
if (fiboDivTen(term))
cout << "Divisible";
else
cout << "Not Divisible";
}
出力
Divisible
この例では term = 45 であり、45は15の倍数なので「Divisible(割り切れる)」と出力されます。このように、実際にフィボナッチ数を求めなくても、剰余演算ひとつで瞬時に判定できるのがこの手法の大きな利点です。
-
Pythonで偶数番目の桁の数字の積がKで割り切れるかどうかを判定する方法
ある整数 n と別の整数 k が与えられたとき、n の偶数番目の桁にある数字の積が k で割り切れるかどうかを判定します。ここで、桁の位置は右から左へ数えるものとし、最も右端の桁を 1 桁目とします。 例えば、入力が n = 59361 の場合を考えてみましょう。右から数えると、各桁の位置と数字は次のようになります。 1桁目:1 2桁目:6 3桁目:3 4桁目:9 5桁目:5 偶数番目(2桁目と4桁目)の数字は 6 と 9 なので、その積は 6 × 9 = 54 となります。54 は 3 で割り切れるため、この場合の出力は True になります。 解決のためのアプローチ この問題
-
PythonでN番目のフィボナッチ数を求める方法|再帰と動的計画法を解説
この記事では、Pythonを使ってN番目のフィボナッチ数を計算する方法を解説します。 フィボナッチ数とは フィボナッチ数は、次の漸化式によって定義される数列です。 Fn = Fn-1 + Fn-2 初期値は F0 = 0、F1 = 1 となります。したがって、フィボナッチ数列の最初のいくつかの項は以下のようになります。 0, 1, 1, 2, 3, 5, 8, 13, ………… フィボナッチ数を求めるには、大きく分けて「再帰」と「動的計画法」の2つのアプローチがあります。それぞれの実装方法をPythonスクリプトで見ていきましょう。 方法1:再帰を使うアプローチ まずは最も直感的な再帰による実