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

C++で積がPとなるN個の整数の最大GCDを求める方法

2つの整数 NP が与えられているとします。PN 個の未知の整数の積であり、そのときそれらの整数の最大公約数(GCD)としてあり得る最大値を求めるのが課題です。

例として、N = 3、P = 24 の場合を考えてみましょう。3つの整数の組み合わせとしては {1, 1, 24}、{1, 2, 12}、{1, 3, 8}、{1, 4, 6}、{2, 2, 6}、{2, 3, 4} などが考えられます。それぞれのGCDは 1, 1, 1, 1, 2, 1 となるため、この場合の答えは 2 です。

解法のアプローチ

まず P のすべての素因数を求め、ハッシュマップに格納します。各素因数が N 個の整数すべてに共通して含まれるとき、GCDは最大になります。

P を次のように素因数分解できるとします。

P = p1k1 × p2k2 × … × pnkn(ここで pi は素因数)

このとき、最大GCDは次の式で求められます。

res = p1k1/N × p2k2/N × … × pnkn/N

つまり、各素因数の指数を N で割った値を累乗として掛け合わせることで、すべての整数に均等に分配できる素因数の分だけGCDを最大化できます。

C++での実装例

#include <iostream>
#include <cmath>
#include <unordered_map>
using namespace std;

long getMaxGCD(long N, long p) {
    int gcd = 1;
    unordered_map<int, int> prime_factors;

    // 素因数分解を行い、指数を記録する
    for (int i = 2; i * i <= p; i++) {
        while (p % i == 0) {
            prime_factors[i]++;
            p /= i;
        }
    }
    if (p != 1)
        prime_factors[p]++;

    // 各素因数の指数をNで割った値を掛け合わせる
    for (auto v : prime_factors)
        gcd = gcd * pow(v.first, v.second / N);

    return gcd;
}

int main() {
    long n = 3;
    long p = 24;
    cout << "MAX GCD: " << getMaxGCD(n, p);
}

出力結果

MAX GCD: 2

このアルゴリズムの計算量は、素因数分解部分が O(√P)、集計部分が O(素因数の種類数) となるため、P が大きくなっても効率的に動作します。

  1. C++でN個の未知整数の積Pから最大GCDを求めるアルゴリズム

    2つの整数 N と P が与えられ、P が N 個の未知の整数の積であるとします。このとき、これらの整数のGCD(最大公約数)を求める必要があります。ただし、同じ積 P になる整数の組み合わせは複数存在し得るため、その中で最も大きなGCDを求めることが目標です。例として、N = 3、P = 24 の場合を考えてみましょう。積が24になる3つの整数の組み合わせには {1, 1, 24}、{1, 2, 12}、{1, 3, 8}、{1, 4, 6}、{2, 2, 6}、{2, 3, 4} などがあり、それぞれのGCDは 1, 1, 1, 1, 2, 1 となります。したがって、この場合の答えは 2

  2. C++でGCDとLCMの値から条件を満たす数のペアの総数を求める方法

    この記事では、最大公約数(GCD)と最小公倍数(LCM)の値が与えられたとき、その両方の条件を満たす整数のペアが全部で何通り存在するかを求める方法を解説します。 例として、GCDが2、LCMが12の場合を考えてみましょう。この条件を満たすペアは (2, 12)、(4, 6)、(6, 4)、(12, 2) の4つです。プログラムの目的は、このペアの総数「4」を計算することです。 解決の鍵となる数学的性質 2つの整数 a と b の間には、次のような重要な関係が常に成り立ちます。 a × b = GCD(a, b) × LCM(a, b) また、a と b はいずれも必ず GCD で割り切れるた