C++で「積が和で割り切れる」1からNまでの数値ペアを数える方法
整数 N が与えられたとき、1 から N までの数値の中から、2 つの数の積がその和で割り切れるようなペア (i, j) の個数を求めるのがこの記事の目標です。
例で理解しよう
入力 − N = 11
出力 − 条件を満たすペアの数:1
説明 − 3 と 6 のペアに注目すると、積は 18、和は 9 であり、9 は 18 を余りなく割り切ることができます。N = 11 の範囲内ではこれが唯一のペアです。
入力 − N = 30
出力 − 条件を満たすペアの数:12
説明 − 該当するペアは次の 12 個です。
(3, 6)、(4, 12)、(5, 20)、(6, 12)、(6, 30)、(8, 24)、(9, 18)、(10, 15)、(12, 24)、(15, 30)、(20, 30)、(21, 28)
プログラムで使うアプローチ
基本的な考え方はシンプルで、FOR ループを二重に回して 1 から N までのすべての数値の組み合わせを調べます。各 i に対して、積 (i × j) が和 (i + j) で割り切れるような j を探し、条件を満たす i ≠ j のペアが見つかるたびにカウントを 1 ずつ増やしていきます。
- 数値 N を入力として受け取ります。
- 関数 Sum_N(N) は N を引数に取り、「積が和で割り切れるペアの個数」を戻り値として返します。
- 外側のループで i を 1 から N 未満まで走査します。
- 内側のループで j を i + 1 から N まで走査します(同じ数同士のペア i = j は除外)。
- カウント用変数 count の初期値を 0 とします。
- 各 (i, j) の組み合わせについて、temp = (i × j) % (i + j) を計算します。
- temp が 0 になれば、和が積を完全に割り切っていることを意味するので、count をインクリメントします。
- すべてのループが終了した時点で、count には条件を満たすペアの総数が格納されています。
- 最後に count を結果として返します。
なお、この手法の時間計算量は O(N²) です。N が大きくなると計算量が急増するため、小〜中規模の N に適した素直な実装と言えます。
コード例
#include <bits/stdc++.h>
using namespace std;
int Sum_N(int N){
int count = 0;
for (int i = 1; i < N; i++){
for (int j = i + 1; j <= N; j++){
int temp = (j * i) % (j + i);
if (!temp){
count++;
}
}
}
return count;
}
int main(){
int N = 20;
cout<<"Count of pairs of numbers from 1 to N with Product divisible by their Sum are: "<<Sum_N(N);
return 0;
}
出力
上記のコードを実行すると、次のような出力が得られます。
Count of pairs of numbers from 1 to N with Product divisible by their Sum are: 6
N = 20 の場合、条件を満たすペアは 6 個存在することが確認できます。(3, 6)、(4, 12)、(5, 20)、(6, 12)、(8, 24)、(9, 18)、(10, 15) のうち、N = 20 以下に収まる組み合わせが該当します。
-
C++で配列内の「割り切れるペア」の数を数える方法
本記事では、任意のサイズの整数型要素を持つ配列が与えられたとき、その中から「一方の要素がもう一方の要素を割り切れる」ようなペア(整除ペア)の総数を求める方法を解説します。 配列とは、同じ型の要素を固定サイズで連続的に格納できるデータ構造の一種です。複数のデータをまとめて管理するために使われますが、「同じ型の変数の集まり」と捉えたほうが理解しやすい場合も多いでしょう。 具体例 入力:int arr[] = {1, 2, 3, 6} 出力:count is 4 説明:(1,2)、(1,3)、(1,6)、(3,6) の4つのペアにおいて、一方の要素が他方の要素を割り切れます。1はあらゆる整数を割り
-
C++で一意の桁(重複しない数字)を持つ数を数える方法
負でない整数 n が与えられたとき、0 以上 10n 未満の範囲に存在する「すべての桁が一意(重複なし)」である数 x の個数を求める問題を考えてみましょう。例えば n = 2 の場合、0 から 100 未満までの数のうち、11、22、33、44、55、66、77、88、99 のように同じ数字が重複している数を除外した個数、つまり 91 が答えとなります。解法のアプローチこの問題は、桁ごとに選べる数字の組み合わせを順番にかけていくことで効率的に解くことができます。手順は以下の通りです。n が 0 の場合は 1 を返します(0 のみが該当するため)。n は最大でも 10 桁しか考慮できないため、