C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++でN以上の最小の素数回文(プライムパリンドローム)を求める方法

この記事では、「N 以上の整数の中で最小となる素数回文(プライムパリンドローム)」を C++ で求めるアルゴリズムを解説します。

例えば N = 13 の場合、答えは 101 になります。13 以上の回文数には 22、33、44 などがありますが、これらはすべて 11 の倍数であるため素数になり得ません。そのため、次に現れる素数回文である 101 が答えとなります。

解法のアプローチ

全ての整数を順に素数かつ回文かどうか調べるのは非効率です。そこで、回文を直接生成することで探索範囲を大幅に絞り込みます。手順は以下の通りです。

  • N が 8 以上 11 以下の場合は、11 を返します(この範囲では 11 だけが素数回文になるための特別なケースです)。

  • i を 1 から 99999 までループします。

    • s := i を文字列に変換したもの

    • r := s のコピーを作り、反転(リバース)する

    • num := s と「r の先頭 1 文字を除いた部分文字列」を連結し、数値に変換する(これにより奇数桁の回文が生成されます)

    • num が N 以上であり、かつ素数であれば num を返す

  • 最後まで見つからなければ 0 を返します。

なお、偶数桁の回文(11 を除く)は必ず 11 の倍数になるため素数ではありません。この性質により、奇数桁の回文だけを生成すればよいことが分かります。

C++での実装例

#include <bits/stdc++.h>
using namespace std;
class Solution {
    public:
    bool isPrime(int n){
       if(n % 2 == 0 && n > 2) return false;
       for(int i = 3; i * i <= n; i++){
          if(n % i == 0) return false;
       }
       return n != 1 && n != 0;
    }
    int primePalindrome(int N) {
       if(8 <= N && N <= 11) return 11;
       for(int i = 1; i < 100000; i++){
          string s = to_string(i);
          string r = s;
          reverse(r.begin(), r.end());
          int num = stoi(s + r.substr(1));
          if(num >= N && isPrime(num)) return num;
       }
       return 0;
    }
};
main(){
    Solution ob;
    cout << (ob.primePalindrome(105));
}

実行結果

入力

105

出力

131

コードのポイント

例えば i = 13 の場合、s = "13"、r = "31" となり、s + r.substr(1) は "131" になります。このように、元の数字の前半部分を鏡写しにすることで、昇順に近い順序で回文を効率的に生成できます。

素数判定は試し割り法を用いており、√n までの奇数で割り切れるかを確認しています。回文の生成と素数判定を組み合わせることで、単純な全探索よりもはるかに高速に答えを見つけられます。

  1. C++による回文分割:最小カット数を求めるアルゴリズム

    回文分割とは 入力として与えられた文字列を、分割後のすべての部分文字列が回文になるように分割することを「回文分割(Palindrome Partitioning)」と呼びます。この記事では、与えられた文字列を回文に分割するために必要な最小のカット数を求めるアルゴリズムを解説します。 例として、文字列「ababbbabbababa」を考えてみましょう。この場合、3回のカットで次のように回文へ分割できます。 a | babbbab | b | ababa アルゴリズムの考え方(動的計画法) この問題は動的計画法(DP)を用いて効率的に解くことができます。まず、n × n の2次元テーブルを2つ用

  2. C++でn番目の平衡素数(バランス素数)を求める方法

    平衡素数とは 平衡素数(Balanced Prime)とは、直前の素数と直後の素数までの距離(差)が等しい素数のことです。言い換えれば、前後にある最も近い素数の平均値に一致する素数を指します。 ある素数が平衡素数であるためには、次の式を満たす必要があります。 Pn = (Pn-1 + Pn+1) / 2 ここで、nは順序付けられた素数列におけるPnのインデックス(順位)を表します。 素数の順序付き集合:2, 3, 5, 7, 11, 13, … 最初のいくつかの平衡素数は、5, 53, 157, 173, … です。 問題の概要 この問題では、数値nが与えられ、n番目の平衡素数を求めることが