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

C++で平方フリー約数の最小個数を求める方法


問題文

整数 N が与えられます。「平方フリー約数(完全平方数ではない約数)」のみを使って N を因数分解するとき、必要となる約数の最小個数を求めてください。

つまり、N の因数分解には、完全平方数とならない約数だけを使用する必要があります。

N = 24 の場合、平方フリーな因子は以下のように 3 つになります。

因数 = 2 × 6 × 2

アルゴリズム

  • まず、N の平方根までのすべての素因数を求めます。
  • 次に、N の平方根以下のすべての素因数について、それぞれ N における最大の冪指数を調べます(例:24 における 2 の最大冪指数は 3)。
  • ある素因数が N の中で 1 より大きい冪を持つ場合、その素因数同士を掛け合わせることはできません(例:24 における 2 の冪指数は 3 ですが、2 × 2 = 4 や 2 × 2 × 2 = 8 はどちらも平方フリーではないため、24 の因数分解には使えません)。これらは必ず何らかの完全平方数で割り切れてしまうからです。
  • 一方、異なる素因数どうしを(1 回だけ)掛け合わせた積は、いかなる完全平方数でも割り切れません。
  • この性質から、「答えは N を構成するすべての素因数の最大冪指数の中で最も大きい値になる」と推察できます。

実装例(C++)

#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
#define MAX 1005
void getPrimes(vector<int>& primes) {
    bool prime[MAX];
    memset(prime, true, sizeof(prime));
    for (int p = 2; p * p < MAX; p++) {
        if (prime[p] == true) {
            for (int i = p * 2; i < MAX; i += p)
                prime[i] = false;
        }
    }
    for (int p = 2; p < MAX; p++)
    if (prime[p])
    primes.push_back(p);
}
int getMinimumSquareFreeDivisors(int n) {
    vector<int> primes;
    getPrimes(primes);
    int maxCnt = 0;
    for (int i = 0; i < primes.size() && primes[i] * primes[i] <= n; i++) {
        if (n % primes[i] == 0) {
            int tmp = 0;
            while (n % primes[i] == 0) {
                tmp++;
                n /= primes[i];
            }
            maxCnt = max(maxCnt, tmp);
        }
    }
    if (maxCnt == 0)
    maxCnt = 1;
    return maxCnt;
}
int main() {
    int n = 24;
    cout << "Minimum number of square free divisors = " << getMinimumSquareFreeDivisors(n) << endl;
    return 0;
}

出力結果

上記のプログラムをコンパイルして実行すると、次の出力が得られます。

Minimum number of square free divisors = 3
  1. C++で最小ページ数を割り当てる方法|二分探索による効率的な解法

    「最小ページ数の割り当て(Allocate Minimum Number of Pages)」は、競技プログラミングや技術面接で頻出する古典的なアルゴリズム問題の一つです。この記事では、問題の内容を詳しく解説し、二分探索を用いた効率的な解法をC++のサンプルコードとともに紹介します。 問題文 n冊の異なる本のページ数が与えられます。また、これらの本を割り当てる対象としてm人の学生がいます。本はページ数の昇順に並べられており、各学生には連続した本のみを割り当てることができます。プログラムは、一人の学生が読むことになる最大ページ数を返しますが、その最大値ができるだけ小さくなるような割り当てを行う

  2. C++でアダム数(Adam Number)を判定する方法

    アダム数(Adam Number)とは、ある数を2乗した結果が、その数の桁を逆順に並べた数の2乗をさらに逆順にしたものと一致するような数のことです。 アダム数の概念 ある数がアダム数であるためには、「元の数の2乗」と「元の数を逆順にした数の2乗をさらに逆順にしたもの」が等しくなる必要があります。具体例で確認してみましょう。 例:12の場合 ・12の2乗は 144 ・12の桁を逆順にすると 21 ・21の2乗は 441 ・441は、144(12の2乗)を逆順にした数と一致します このように12はアダム数です。同様に、13や31などもアダム数に該当します(13² = 169、31² = 961