C++である数が別の数のすべての素因数で割り切れるかどうかを判定する方法
問題の概要
2つの整数が与えられたとき、一方の数がもう一方の数のすべての素因数で割り切れるかどうかを判定します。
例として、ある数が 120 の場合、その素因数は {2, 3, 5} です。もう一方の数が 75 であれば、その素因数は {3, 5} となります。120 は 3 でも 5 でも割り切れるため、この場合の答えは「Yes」です。
アルゴリズムの考え方
この問題は、最大公約数(GCD)を利用することで効率的に解くことができます。手順は以下の通りです。
- もし相手の数が 1 であれば、素因数を一切持たないため、答えは常に true になります。
- それ以外の場合は、まず2つの数の GCD を求めます。
- GCD が 1 であれば、両者は互いに素(共素)であり、共通の素因数を持たないため、答えは false です。
- GCD が 1 より大きい場合、その GCD には最初の数 x をも割り切る素因数が含まれています。したがって、「y のすべての素因数が x を割り切る」ことは「y / GCD のすべての素因数が x を割り切る」ことと同値になります。
- そこで、ペア (x, y / GCD) に対して同じ判定を再帰的に適用していきます。
C++による実装例
#include <iostream>
#include <algorithm>
using namespace std;
bool isDivisible(int a, int b) {
if (b == 1)
return true;
int gcd = __gcd(a, b);
if (gcd == 1)
return false;
return isDivisible(a, b / gcd);
}
int main() {
int a = 120, b = 75;
if (isDivisible(a, b))
cout << a << " can be divisible by all prime factors of " << b;
else
cout << a << " can NOT be divisible by all prime factors of " << b;
}
出力結果
120 can be divisible by all prime factors of 75
処理の流れを追ってみる
a = 120、b = 75 の場合の動作を確認してみましょう。
- gcd(120, 75) = 15 → 15 ≠ 1 なので処理を継続
- isDivisible(120, 75 / 15)、すなわち isDivisible(120, 5) を再帰呼び出し
- gcd(120, 5) = 5 → 処理を継続
- isDivisible(120, 5 / 5)、すなわち isDivisible(120, 1) を再帰呼び出し
- b = 1 となったので true を返却
このように、GCD で割り進めることで素因数を一つずつ「消費」していき、最終的に b が 1 になれば、y のすべての素因数が a を割り切ることが保証されます。
補足:__gcd() について
__gcd() は GCC 固有の内部関数です。C++17 以降の環境では、標準ライブラリの std::gcd()(ヘッダー <numeric>)を使用することが推奨されます。移植性を重視する場合はこちらを採用しましょう。
-
C++で巨大な数値が15で割り切れるかどうかを判定する方法
本記事では、ある数値が15で割り切れるかどうかを判定する方法を解説します。ここで扱う数値は非常に大きいため、通常の整数型では表現しきれず、文字列として扱います。 15の倍数判定の考え方 数値が15で割り切れるためには、「5で割り切れる」かつ「3で割り切れる」という2つの条件を満たす必要があります。これは、15 = 5 × 3 であり、5と3が互いに素であるためです。 5で割り切れる条件: 最後の桁(1の位)が「0」または「5」であること 3で割り切れる条件: 各桁の数字の合計が3で割り切れること C++での実装例 #include <bits/stdc++.h> using n
-
関数を使って素数を判定するC++プログラムの作成方法
素数とは、1より大きい整数であり、約数が「1」と「その数自身」のみである数のことを指します。言い換えれば、素数はそれ以外のどの整数でも割り切ることができません。 最初のいくつかの素数は以下の通りです。 2, 3, 5, 7, 11, 13 ,17 本記事では、関数を使用してある数値が素数かどうかを判定するC++プログラムについて解説します。 サンプルコード #include <iostream> using namespace std; void isPrime(int n) { int i, flag = 0; for(i=2; i<=n/2; ++i)