C++で指定した値と等しいGCD(最大公約数)を持つ自然数のペアを数える方法
この記事では、3つの入力変数「start(開始値)」「end(終了値)」「number(指定値)」が与えられたとき、startからendの範囲内にあり、かつGCD(最大公約数)が「number」と等しい数のペアを求める方法を解説します。つまり、GCD(A, B) = number を満たし、AとBがどちらも範囲 [start, end] 内に含まれるようなペア (A, B) の個数をカウントします。
具体例で確認してみましょう。
入力 − start=5, end=20, number=8
出力 − GCDが指定値と等しい自然数のペアの個数 − 3
説明 − 5から20の範囲でGCDが8となるペアは (8,8)、(8,16)、(16,8) の3つです。
入力 − start=5, end=20, number=7
出力 − GCDが指定値と等しい自然数のペアの個数 − 2
説明 − 5から20の範囲でGCDが7となるペアは (21,28)、(28,21) の2つです。
素朴なアプローチ(ナイーブ法)
まず紹介するのは最もシンプルな方法です。外側のforループを i=start から i<=end まで、内側のforループを j=start から j<=end まで回し、各ペア (i, j) について GCD(i, j) == number が成り立つかどうかを判定します。条件を満たしていればカウントを1増やします。
- 変数 start、end、number を整数として受け取ります。
- 関数 GCD(int a, int b) は再帰的に呼び出され、引数 a と b の最大公約数を返します。
- b が0でなければ GCD(b, a % b) として自分自身を再帰呼び出しし、b が0なら a を返します。
- 関数 GCD_pairs(int start, int end, int number) は境界値 start・end と指定値 number を受け取り、GCDが number と等しいペアの個数を返します。
- カウントの初期値を0に設定します。
- ペアの各要素に対して二重のforループを使用します。外側のループは i=start から i<=end まで、内側のループは j=start から j<=end まで繰り返します。
- ペア (i, j) について GCD(i, j) == number が成立するかをチェックし、真であればカウントを増やします。
- 最終的に、GCDが number と等しいペアの総数が得られます。
- そのカウントを結果として返します。
効率的なアプローチ
次に、計算量を大幅に削減できる効率的な方法を紹介します。ペア (i, j) のGCDが number になるためには、i と j の両方が number で割り切れる必要があります。start から end の間で number で割り切れる数は最大でも (end - start) / number 個程度しか存在しないため、探索範囲を絞り込むことができます。具体的には、start = (start + number - 1) / number から end = end / number までの範囲にスケールダウンして走査します。そして、その範囲内の各数について GCD(i, j) == 1 が成り立てば、元のペアのGCDは number になるため、カウントを増やします。
- 変数 start、end、number を整数として受け取ります。
- start = (start + number - 1) / number、end = end / number として更新します。
- 関数 GCD(int a, int b) は再帰的に呼び出され、引数 a と b の最大公約数を返します。
- b が0でなければ GCD(b, a % b) として自分自身を再帰呼び出しし、b が0なら a を返します。
- 関数 GCD_pairs(int start, int end, int number) は境界値 start・end と指定値 number を受け取り、該当するペアの個数を返します。
- カウントの初期値を0に設定します。
- 二重のforループでペアの各要素を走査します。外側のループは i=start から i<=end まで、内側のループは j=start から j<=end まで繰り返します。
- ペア (i, j) について GCD(i, j) == 1 が成立するかをチェックし、真であればカウントを増やします。
- 最終的に、GCDが number と等しいペアの総数が得られます。
- そのカウントを結果として返します。
コード例(ナイーブ法)
#include <bits/stdc++.h>
using namespace std;
int GCD(int a, int b){
return b ? GCD(b, a % b) : a; }
int GCD_pairs(int start, int end, int number){
int count = 0;
for (int i = start; i <= end; i++){
for (int j = start; j <= end; j++){
if (GCD(i, j) == number){
count++;
}
}
}
return count;
}
int main(){
int start = 10, end = 30, number = 10;
cout<<"Count of pairs of natural numbers with GCD equal to given number are: "<<GCD_pairs(start, end, number) << endl;
return 0;
}出力
上記のコードを実行すると、以下の出力が生成されます −
Count of pairs of natural numbers with GCD equal to given number are: 7
コード例(効率的なアプローチ)
#include <bits/stdc++.h>
using namespace std;
int GCD(int a, int b){
return b ? GCD(b, a % b) : a;
}
int GCD_pairs(int start, int end, int number){
int count = 0;
for (int i = start; i <= end; i++){
for (int j = start; j <= end; j++){
if (GCD(i, j) == 1){
count++;
}
}
}
return count;
}
int main(){
int start = 10, end = 30, number = 10;
start = (start + number - 1) / number;
end = end / number;
cout<<"Count of pairs of natural numbers with GCD equal to given number are: "<<GCD_pairs(start, end, number) << endl;
return 0;
}出力
上記のコードを実行すると、以下の出力が生成されます −
Count of pairs of natural numbers with GCD equal to given number are: 7
-
C++で差がkに等しいすべての異なるペアを数える方法
はじめにこのチュートリアルでは、C++を使って「差がkに等しい異なるペア」を見つけて数える方法を解説します。具体的には、整数型の配列と値kが与えられ、その中から差がちょうどkとなるすべての異なるペアを数えることが課題です。アルゴリズムの考え方最もシンプルなアプローチは、配列の要素を1つずつ順番に選び、それ以降の要素との差をすべてチェックする方法です。2つの要素の差がkに等しければ、カウンターを1つ増やします。例えば、配列 {1, 5, 3, 4, 2}、k = 3 の場合、差が3となるペアは (1, 4) と (5, 2) の2つなので、答えは2になります。実装例#include<ios
-
【C++】指定されたインデックスのN個のフィボナッチ数のGCDを効率的に求める方法
本記事では、指定された複数のインデックスに対応するN個のフィボナッチ数の最大公約数(GCD)を、C++で効率的に求める方法を解説します。 フィボナッチ数列と問題の概要 まずおさらいとして、フィボナッチ数列は「0, 1, 1, 2, 3, 5, 8, 13, 21, 34, …」のように、直前の2つの項の和によって定義される数列です。インデックスは0から始まるため、0番目の要素は0、1番目の要素は1となります。 例えば、インデックス{2, 3, 4, 5}に対応するフィボナッチ数は{1, 2, 3, 5}であり、これらのGCDは1です。 鍵となる性質:GCD(Fibo(i), Fibo(j))