C++でn番目の平衡素数(バランス素数)を求める方法
平衡素数とは
平衡素数(Balanced Prime)とは、直前の素数と直後の素数までの距離(差)が等しい素数のことです。言い換えれば、前後にある最も近い素数の平均値に一致する素数を指します。
ある素数が平衡素数であるためには、次の式を満たす必要があります。
Pn = (Pn-1 + Pn+1) / 2
ここで、nは順序付けられた素数列におけるPnのインデックス(順位)を表します。
素数の順序付き集合:2, 3, 5, 7, 11, 13, …
最初のいくつかの平衡素数は、5, 53, 157, 173, … です。
問題の概要
この問題では、数値nが与えられ、n番目の平衡素数を求めることが求められます。
具体例を見てみましょう。
入力 : n = 3 出力 : 157
解法のアプローチ
まず、エラトステネスの篩を用いて素数を生成し、ベクター(動的配列)に格納します。その後、各素数について「前後の素数の平均値と一致するか」を順に判定し、平衡素数であればカウントを1つ増やします。カウントがnに達した時点で、その素数の値を返して処理を終了します。
C++での実装例
#include<bits/stdc++.h>
#define MAX 501
using namespace std;
int balancedprimenumber(int n){
bool prime[MAX+1];
memset(prime, true, sizeof(prime));
for (int p = 2; p*p <= MAX; p++){
if (prime[p] == true)
{
for (int i = p*2; i <= MAX; i += p)
prime[i] = false;
}
}
vector<int> v;
for (int p = 3; p <= MAX; p += 2)
if (prime[p])
v.push_back(p);
int count = 0;
for (int i = 1; i < v.size(); i++){
if (v[i] == (v[i+1] + v[i - 1])/2)
count++;
if (count == n)
return v[i];
}
}
int main(){
int n = 3;
cout<<balancedprimenumber(n)<<endl;
return 0;
}
出力
157
コードのポイント
このプログラムでは、まずブール型の配列を使ってエラトステネスの篩を実装し、MAX(501)以下の素数を効率的に抽出しています。奇数のみをベクターに格納することで、無駄な計算を省いています。その後、隣接する3つの素数の関係を調べることで平衡素数を判定し、n番目に到達した時点で結果を返します。計算量は篩の部分でO(MAX log log MAX)程度に抑えられるため、十分に高速に動作します。
-
【C++】メルセンヌ素数を求めるプログラムの作り方を解説
メルセンヌ素数とは数学におけるメルセンヌ素数とは、「2の冪乗から1を引いた値」に該当する素数のことです。すなわち、ある整数 n に対して Mn = 2n − 1 の形で表される素数を指します。本記事では、入力された正の整数 n 未満のメルセンヌ素数をすべて出力するC++プログラムの実装方法を解説します。メルセンヌ素数となる指数 n は 2, 3, 5, 7, … と続きます。これらに対応するメルセンヌ素数は、それぞれ 3, 7, 31, 127 です。アルゴリズムメルセンヌ素数を求める基本的な手順は以下のとおりです。1. 与えられた数 n 以下のすべての素数を生成する(エラトステネスの篩を利用
-
C++で数値が完全素数(フルプライム)かどうかを判定する方法
完全素数(フルプライム)とは?本記事では、ある数値が「完全素数(フルプライム)」であるかどうかを判定する方法を解説します。完全素数とは、その数値自体が素数であり、かつ各桁の数字もすべて素数である数のことです。例えば、37は2桁とも素数の数字(3と7)で構成され、数値全体も素数であるため、完全素数です。一方、97は数値自体は素数ですが、各桁に9という素数でない数字が含まれているため、完全素数ではありません。判定のアプローチ効率的な判定方法は以下の2段階で行います。まず、素数でない桁が含まれていないかを確認します。各桁の数字は0から9の範囲に収まるため、この範囲で素数となるのは2、3、5、7の4つ