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 など
問題を理解するための具体例
入力: n = 128 出力: 質素数である 説明: 128 の素因数分解は 2^7 で、その桁数は 2。 128 自身の桁数は 3。 したがって、128 は質素数です。
解法アプローチ
この問題を解く基本的な手順は以下の通りです。
- n の素因数をすべて求める。
- 素因数分解の表現(底と指数を含む)全体の桁数を数える。
- 元の数 n 自身の桁数を数える。
- 元の数の桁数が素因数分解表現の桁数より大きければ「質素数」、そうでなければ「質素数ではない」と判定する。
C++ 実装例
以下は、上記の解法を実装した C++ プログラムです。素数の列挙にはエラトステネスの篩を使用しています。
#include <bits/stdc++.h>
using namespace std;
// エラトステネスの篩で n 未満の素数をすべて求める
vector<long int> calcPrimeNum(long int n){
bool primeNos[n + 1];
memset(primeNos, true, sizeof(primeNos));
for (int i = 2; i * i <= n; i++) {
if (primeNos[i] == true) {
for (int j = i * 2; j <= n; j += i)
primeNos[j] = false;
}
}
vector<long int> allPrimeNumbers;
for (int i = 2; i < n; i++)
if (primeNos[i])
allPrimeNumbers.push_back(i);
return allPrimeNumbers;
}
// 数値の桁数を数える関数
int countNumDigits(long int n){
long long int num = n;
int digitCount = 0;
while (num != 0) {
num = num / 10;
digitCount++;
}
return digitCount;
}
// n が質素数かどうかを判定する関数
bool isFrugalNum(long int n){
vector<long int> primeNum = calcPrimeNum(n);
long int num = n;
long int factorDigitCount = 0;
for (int i = 0; i < primeNum.size(); i++) {
if (num % primeNum[i] == 0) {
long int k = 0;
while (num % primeNum[i] == 0) {
num = num / primeNum[i];
k++;
}
// 素因数の桁数に加え、指数が 1 より大きい場合は指数の桁数も加算
if (k == 1)
factorDigitCount += countNumDigits(primeNum[i]);
else
factorDigitCount += countNumDigits(primeNum[i]) + countNumDigits(k);
}
}
return (countNumDigits(n) > factorDigitCount && factorDigitCount != 0);
}
int main(){
long int n = 625;
cout << "The number " << n << " is ";
isFrugalNum(n) ? cout << "a Frugal number\n" : cout << "not a Frugal number\n";
return 0;
}
実行結果
The number 625 is a Frugal number
まとめ
質素数の判定は、「素因数分解の表現の桁数」と「元の数の桁数」を比較するだけで実現できます。エラトステネスの篩で素数を事前に求めておくことで、効率よく素因数分解を行える点がポイントです。ぜひ実際にコードを動かして、さまざまな数で試してみてください。
-
C++で五胞体数(ペンタトープ数)を求める方法
五胞体数とは? 五胞体数(ペンタトープ数)は、パスカルの三角形の第5の対角線上に現れる数列として知られています。この数列を定義するには、パスカルの三角形に少なくとも5つの数が必要となるため、数列の最初の数はパスカルの三角形の第4行である 1 4 6 4 1 から始まります。 本チュートリアルでは、n番目の五胞体数を求める方法を解説します。まずは具体的な例を見てみましょう。 入力 : 1出力 : 1入力 : 4出力 : 35 以下の図から出力を確認できます。 この問題は数列に関するものなので、解法ではまず数列のパターンを見つけることから始めます。 解法のアプローチ このプログラムでは、数列の
-
C++でアダム数(Adam Number)を判定する方法
アダム数(Adam Number)とは?本記事では、与えられた整数がアダム数(Adam Number)であるかどうかを判定するC++プログラムの作成方法を解説します。まずは、アダム数とはどのような数なのかを確認しておきましょう。アダム数とは、ある数 n の2乗と、n の各桁を逆順に並べ替えた数の2乗が、互いに逆順の関係になっている数のことです。具体例として「13」を見てみます。13を逆順にすると「31」になります。・13 × 13 = 169・31 × 31 = 961169 と 961 は互いに逆順の関係にあるため、13 はアダム数であると言えます。アダム数の判定手順与えられた数がアダム数か