C++でほぼ完全数(Almost Perfect Number)を判定する方法
ほぼ完全数(Almost Perfect Number)とは?
ほぼ完全数(Almost Perfect Number)は、「最小不足数(least deficient number)」や「わずかに不足した数(slightly defective number)」とも呼ばれる特殊な数です。その約数の総和(1とその数自身を含む)が 2n-1 に等しくなる数を指します。
本記事では、与えられた数がほぼ完全数であるかどうかを判定するアルゴリズムを、具体例を交えながら解説します。
具体例で理解する
まず、例を見ながら概念を確認しましょう。
入力:16
出力:Yes
説明:
16の約数は 1, 2, 4, 8, 16 です。
合計 = 1 + 2 + 4 + 8 + 16 = 31
n = 16 のとき、2n-1 = 2×16 - 1 = 31
入力:12
出力:No
説明:
12の約数は 1, 2, 3, 4, 6, 12 です。
合計 = 1 + 2 + 3 + 4 + 6 + 12 = 26
n = 12 のとき、2n-1 = 2×12 - 1 = 23
16の場合、約数の総和が 2n-1 と一致するためほぼ完全数ですが、12の場合は総和が 2n-1 より大きいため、ほぼ完全数ではありません。このように、約数の総和が 2n-1 と一致するかどうかを確認することで判定できます。
アルゴリズム
判定の手順は以下の通りです。
ステップ1:その数のすべての約数の総和を計算する。
ステップ2:val = 2n-1 の値を計算する。
ステップ3:sum == val の場合 →「YES」と出力する。
ステップ4:それ以外の場合 →「NO」と出力する。
C++での実装例
#include <iostream>
using namespace std;
void almostPerfectNumber(int n);
int main(){
int n = 16;
cout<<"Is "<<n<<" an almost perfect number ?\n";
almostPerfectNumber(n);
}
void almostPerfectNumber(int n){
int divisors = 0;
for (int i = 1; i <= n; i++) {
if (n % i == 0)
divisors += i;
}
if (divisors == 2 * n - 1)
cout<<"YES";
else
cout<<"NO";
}
出力結果
Is 16 an almost perfect number ?
YES
このプログラムでは、1からnまでの数を順に確認し、nを割り切れる数(約数)をすべて合計しています。その合計が 2n-1 と一致すれば「YES」、一致しなければ「NO」を出力します。
補足:計算量を改善するには
上記の実装は計算量が O(n) ですが、約数はペアで現れる(i と n/i の組み合わせ)という性質を利用すると、√n まで調べるだけでよいため、計算量を O(√n) まで改善できます。大きな数を扱う場合にはこちらの方法が効率的です。
なお、数学的に興味深い点として、2のべき乗(1, 2, 4, 8, 16, ...)はすべてほぼ完全数であることが知られています。一方、奇数のほぼ完全数が存在するかどうかは、未解決の問題となっています。
-
C++で質素数(Frugal Number)を判定する方法【サンプルコード付き】
この記事では、正の整数 N が与えられたときに、その数が質素数(Frugal Number)であるかどうかを判定するプログラムを C++ で作成する方法を解説します。 質素数とは? 質素数(FRUGAL NUMBER)とは、その数自身の桁数が、素因数分解による表現の桁数よりも厳密に大きい数のことです。 例:625 の場合 625 を素因数分解すると 54 となります。 625 自身の桁数:3 桁 54 の表現の桁数:2 桁 3 は 2 よりも厳密に大きいため、625 は質素数です。 最初のいくつかの質素数:125、128、243、256、343、512、625 など 問題を理解するための具
-
C++で五胞体数(ペンタトープ数)を求める方法
五胞体数とは? 五胞体数(ペンタトープ数)は、パスカルの三角形の第5の対角線上に現れる数列として知られています。この数列を定義するには、パスカルの三角形に少なくとも5つの数が必要となるため、数列の最初の数はパスカルの三角形の第4行である 1 4 6 4 1 から始まります。 本チュートリアルでは、n番目の五胞体数を求める方法を解説します。まずは具体的な例を見てみましょう。 入力 : 1出力 : 1入力 : 4出力 : 35 以下の図から出力を確認できます。 この問題は数列に関するものなので、解法ではまず数列のパターンを見つけることから始めます。 解法のアプローチ このプログラムでは、数列の