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

【C++】範囲内の「素因数が2と3のみ」の数を数える方法

2つの整数 STARTEND が与えられ、この2つで数値の範囲を定義します。この記事のゴールは、範囲 [START, END] 内に存在する「素因数が2と3だけ」の数、すなわち 2a × 3b(a, b は 0 以上の整数)の形で表せる数を見つけ出し、その個数を求めることです。

調べ方はシンプルです。START から END まで順に各数値を走査し、それぞれの数が2と3だけで割り切れるかを確認します。割り切れる場合は実際に割って数を小さくしていき、どちらでも割れなくなった時点でループを抜けます。最終的にその数が1にまで約分されていれば、素因数は2と3のみであると判定できます。

それでは、具体例で確認しましょう。

入力例 1

START=20 END=25

出力例 1

素因数が2と3のみの数: 1

説明

各数の素因数分解:
20 = 2×2×5
21 = 3×7
22 = 2×11
23 = 23(素数)
24 = 2×2×2×3
25 = 5×5
素因数が2と3だけなのは 24 のみです。

入力例 2

START=1000 END=1500

出力例 2

素因数が2と3のみの数: 4

説明

1024、1152、1296、1458 の4つが該当する数です。

プログラムで使用するアプローチ

  • 範囲を表す整数 START と END を入力として受け取ります。
  • 関数 twothreeFactors(int start, int end) が範囲を受け取り、素因数が2と3のみの数の個数を返します。
  • カウント用変数 count を 0 で初期化します。
  • for ループで i = start から i = end まで、範囲内の数を順に走査します。
  • 各数値 num = i に対して、while ループ内で num % 2 == 0 であれば 2 で割ります。
  • 続いて num % 3 == 0 であれば 3 で割ります。どちらでも割り切れない場合は break で while ループを抜けます。
  • while ループ終了後も num が 1 になっていれば count をインクリメントします。
  • すべてのループが完了した時点で、count には素因数が2と3のみの数の総数が格納されています。
  • count を結果として返します。

計算量を考えてみましょう。範囲内の各数値に対して行う除算は、数を2以上の倍率で縮小していくため高々 log₂N 回程度であり、全体の計算量は O((END − START + 1) × log N) となります。非常に効率的なアプローチです。

C++ 実装例

#include <bits/stdc++.h>
using namespace std;

int twothreeFactors(int start, int end){
    // 1 が誤ってカウントされないよう、start が 1 なら 2 から開始する
    if (start == 1)
        { start++; }
    int count = 0;
    for (int i = start; i <= end; i++) {
        int num = i;
        while(num>1){
            // 2 で割り切れる場合は 2 で割る
            if(num % 2 == 0)
                { num /= 2; }
            // 3 で割り切れる場合は 3 で割る
            else if (num % 3 == 0)
                { num /= 3; }
            else // 2 でも 3 でも割り切れない場合はループを抜ける
                { break; }
        }
        // 1 に約分されていれば、素因数は 2 と 3 のみということ
        if (num == 1)
            { count++; }
    }
    return count;
}

int main(){
    int START = 10, END = 20;
    cout << "素因数が2と3のみの数:" << twothreeFactors(START, END);
    return 0;
}

実行結果

上記のコードを実行すると、次の出力が得られます。

素因数が2と3のみの数:3

START=10、END=20 の場合、12(= 2×2×3)、16(= 2×2×2×2)、18(= 2×3×3)の3つが条件を満たすため、結果は 3 となります。

  1. C++で1からNまでの準素数(Almost Prime)の個数を求める方法

    ある数 N が与えられたとき、1からNまでの範囲に含まれる「準素数(almost prime)」の個数を求める問題を考えてみましょう。準素数とは、異なる素因数をちょうど2つ持つ数のことです。素因数以外の約数(合成数の約数)はいくつあっても構いませんが、その中に含まれる素因数は正確に2種類である必要があります。例えば、Nが10の場合、出力は2になります。これは、条件を満たす数が 6(= 2 × 3)と 10(= 2 × 5)の2つしか存在しないためです。アプローチ:エラトステネスの篩を活用するこの問題を効率的に解くには、エラトステネスの篩(Sieve of Eratosthenes)を使って素数

  2. 【C++】合計と最大公約数(GCD)が与えられた2つの数を求める方法

    この記事では、2つの数 a と b の合計(sum)と最大公約数(GCD)が与えられたときに、元の2つの数を復元する方法を解説します。条件を満たす組み合わせが存在しない場合は -1 を返します。 例えば、合計が 6、GCDが 2 とすると、答えは 4 と 2 になります(4 + 2 = 6、gcd(4, 2) = 2 を満たすため)。 考え方(アプローチ) GCDが分かっているということは、2つの数がどちらもGCDの倍数であることが確定します。この性質を利用すると、次の手順で答えを導き出せます。 候補の生成: 片方の数をGCDそのものと仮定すると、もう片方は「合計 − GCD」となります。