C++で素数トリプレット(三つ組の素数)をすべて求める方法
問題の概要
この問題では、ある数値 N が与えられ、N未満のすべての素数トリプレットを見つけて出力することが求められます。
素数トリプレットとは
素数トリプレットとは、3つの素数からなる組のことで、次のいずれかの形で表されます。
- (p, p+2, p+6)
- (p, p+4, p+6)
5以上の素数は必ず「6k±1」の形で表されるため、素数はこのパターンに従って三つ組にグループ化されます。
入出力例
入力:N = 13 出力:5 7 11
解法のアプローチ
この問題を解くには、まずN以下のすべての素数を求め、その後トリプレットの条件に合致するかどうかを確認します。素数の列挙にはエラトステネスの篩を用いることで、効率的に処理できます。
- エラトステネスの篩でN以下の素数をすべて求める。
- 各数値 i について、(i, i+2, i+6) または (i, i+4, i+6) の3つがすべて素数かどうかを判定する。
- 条件を満たす組をすべて出力する。
C++での実装例
#include <bits/stdc++.h>
using namespace std;
void findPrimes(int n, bool prime[]) {
for (int p = 2; p * p <= n; p++) {
if (prime[p] == true) {
for (int i = p * 2; i <= n; i += p)
prime[i] = false;
}
}
}
void printPrimeTriplets(int n) {
bool prime[n + 1];
memset(prime, true, sizeof(prime));
findPrimes(n, prime);
for (int i = 2; i <= n-6; ++i) {
if (prime[i] && prime[i + 2] && prime[i + 6])
cout<<i<<"\t"<<(i+2)<<"\t"<<(i+6)<<endl;
else if (prime[i] && prime[i + 4] && prime[i + 6])
cout<<i <<"\t"<<(i + 4)<<"\t"<<(i + 6)<<endl;
}
}
int main() {
int N = 15;
cout<<"Prime Triplets Less than "<<N<<" are :\n";
printPrimeTriplets(N);
return 0;
}出力結果
Prime Triplets Less than 15 are : 5 7 11 7 11 13
計算量について
エラトステネスの篩による素数生成の時間計算量は O(N log log N)、トリプレットの判定は配列を一度走査するだけなので O(N) です。したがって、全体の計算量は O(N log log N) となり、非常に効率的なアルゴリズムといえます。
-
C++でn番目の平衡素数(バランス素数)を求める方法
平衡素数とは 平衡素数(Balanced Prime)とは、直前の素数と直後の素数までの距離(差)が等しい素数のことです。言い換えれば、前後にある最も近い素数の平均値に一致する素数を指します。 ある素数が平衡素数であるためには、次の式を満たす必要があります。 Pn = (Pn-1 + Pn+1) / 2 ここで、nは順序付けられた素数列におけるPnのインデックス(順位)を表します。 素数の順序付き集合:2, 3, 5, 7, 11, 13, … 最初のいくつかの平衡素数は、5, 53, 157, 173, … です。 問題の概要 この問題では、数値nが与えられ、n番目の平衡素数を求めることが
-
C++で数値が完全素数(フルプライム)かどうかを判定する方法
完全素数(フルプライム)とは?本記事では、ある数値が「完全素数(フルプライム)」であるかどうかを判定する方法を解説します。完全素数とは、その数値自体が素数であり、かつ各桁の数字もすべて素数である数のことです。例えば、37は2桁とも素数の数字(3と7)で構成され、数値全体も素数であるため、完全素数です。一方、97は数値自体は素数ですが、各桁に9という素数でない数字が含まれているため、完全素数ではありません。判定のアプローチ効率的な判定方法は以下の2段階で行います。まず、素数でない桁が含まれていないかを確認します。各桁の数字は0から9の範囲に収まるため、この範囲で素数となるのは2、3、5、7の4つ