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

C++で指定された長さの連続する合成数の範囲を求める方法

正整数 n が与えられたとき、「範囲内のすべての数が合成数であり、かつ範囲の長さがちょうど n となる」ような正整数の範囲を求める問題を考えます。条件を満たす範囲が複数存在する場合は、そのうちのどれか1つを出力すれば構いません。なお、合成数(composite number)とは「1 とその数自身以外に、少なくとも1つの約数を持つ数」のことです。

アルゴリズムの考え方

範囲の長さが n である以上、先頭の数を a とすると、範囲内の残りの数は a + 1, a + 2, …, a + n − 1 となり、これらがすべて合成数でなければなりません。

ここで役立つのが階乗(factorial)の性質です。正整数 p に対して、p! は 2, 3, 4, …, p − 1 のすべてを約数として持ちます。したがって、2 ≤ i ≤ p を満たす任意の i について、p! + i は必ず i を約数に含むため、必ず合成数になります。

つまり、p! + 2, p! + 3, …, p! + p − 1 はすべて合成数であり、範囲 [p! + 2, p! + p − 1] を出力すればよいことになります。この範囲に含まれる数は p − 2 個なので、長さ n の範囲を得るには p = n + 2 と置きます。こうして得られる範囲は [(n+2)! + 2, (n+2)! + n + 1] となり、ちょうど n 個の連続する合成数から構成されます。

C++での実装例

#include<iostream>
using namespace std;
int fact (int n) {
    if (n == 0)
        return 1;
    return n * fact(n-1);
}
void showRange(int n) {
    int a = fact(n + 2) + 2;
    int b = a + n - 1;
    cout << "[" << a << ", " << b << "]";
}
int main() {
    int n = 3;
    showRange(n);
}

コードの解説

fact 関数は再帰呼び出しによって階乗を計算します。showRange 関数では、範囲の先頭を a = (n + 2)! + 2 とし、末尾を b = a + n − 1 として求め、その範囲を標準出力に表示します。

出力結果

[122, 124]

例として n = 3 の場合、(n + 2)! = 5! = 120 となるため、範囲は [122, 124] になります。122 = 2 × 61、123 = 3 × 41、124 = 4 × 31 と、いずれも合成数であることが確認できます。

注意点

階乗は極めて大きな値に増加するため、n が大きくなると int 型ではすぐにオーバーフローを起こします。実用上は long long 型や多倍長整数ライブラリの利用を検討してください。

  1. C++で指定された制約条件下で重複要素を検索する方法

    問題の概要6種類の異なる数値からなるリストがあり、そのうち1つの数値だけが5回繰り返し出現しています。つまり、配列には合計10個の要素が存在することになります。この重複している数値を、たった2回の比較だけで見つけ出すのが本記事の課題です。例えば、リストが [1, 2, 3, 4, 4, 4, 4, 4, 5, 6] の場合、重複している数値は 4 なので、出力は「4」となります。アルゴリズムの考え方ここでは、配列が昇順にソートされているものとします。合計10個の要素の中に同じ数値が5個連続して並んでいる場合、そのブロックは必ずインデックス3から5の範囲のいずれかに位置します。これは、5個の連続

  2. 【C++】指定された範囲内で x が y を割り切るペア(x, y)を O(1) で見つける方法

    今回は興味深いアルゴリズムの問題を取り上げます。範囲 l ≤ x, y ≤ r を満たすペア(x, y)を見つけるというもので、このペアには「x が y を割り切る」という性質が必要です。条件を満たすペアが複数存在する場合は、そのうちの 1 つを出力すればよいことになっています。解法のアイデアこの問題は、実は O(1) の計算量で解くことができます。鍵となるのは、下限値 l とその 2 倍の値 2l です。その理由を考えてみましょう。y/x の最小値は 2 です。もし範囲内により大きな値(y/x ≥ 3 となる組み合わせ)が存在するなら、必ず y/x = 2 となる組み合わせも同じ範囲内に存在