C++で10^18までの大きな整数を素因数分解し、出現回数を求める方法
問題概要
この問題では、1018以下の整数 N が与えられ、その素因数とそれぞれの出現回数(指数)をすべて出力することが求められます。
具体例を見てみましょう。
入力:100 出力:2 2 5 2 説明:100 の素因数分解は 100 = 2 × 2 × 5 × 5 となります。
解き方のアプローチ
この問題を解くには、まず対象の数の素因数をすべて求め、その後それぞれの素因数が出現する回数を数える必要があります。手順は以下の通りです。
- まず、2 が因数として何回含まれるかを確認し、割り切れる限り数を 2 で割り続けます。
- 次に、3 から √n までの奇数を順に調べ、その数の因数となる素数が見つかるたびに割り算を行い、出現回数をカウントします。
- 数が 1 になった時点で処理を終了します。
- 最後に、すべての素因数とその出現回数を出力します。
ポイントとして、√n より大きい素因数は高々 1 つしか存在しないため、ループ終了後に n が 2 より大きければ、その値自体が最後の素因数として残っていることになります。
実装例
以下のコードは、上記の解法を実装したものです。
#include <iostream>
#include <math.h>
using namespace std;
void factorize(long long n){
int count = 0;
while (!(n % 2)) {
n/= 2;
count++;
}
if (count)
cout<<2<<"\t"<<count<<endl;
for (long long i = 3; i <= sqrt(n); i += 2) {
count = 0;
while (n % i == 0) {
count++;
n = n / i;
}
if (count)
cout<<i<<"\t"<<count<<endl;
}
if (n > 2)
cout<<n<<"\t"<<1<<endl;
}
int main() {
long long N = 21000;
cout<<"The prime factors and their frequencies of the number "<<N<<" are \n";
factorize(N);
return 0;
}出力結果
The prime factors and their frequencies of the number 21000 are 2 3 3 1 5 3 7 1
計算量について
この手法は「試し割り法」と呼ばれる古典的な素因数分解アルゴリズムで、計算量は O(√n) となります。1018 程度の大きな整数でも、√(1018) = 109 回程度の演算で処理できるため、C++のような高速な言語であれば現実的な時間で素因数分解が可能です。また、偶数を先に取り除いた後は奇数のみを試すことで、さらに約半分の計算量に抑えられる点も工夫されています。
-
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 以下の図から出力を確認できます。 この問題は数列に関するものなので、解法ではまず数列のパターンを見つけることから始めます。 解法のアプローチ このプログラムでは、数列の