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

配列のGCDをkの倍数にするための最小操作回数をC++で求める方法

問題の概要

配列 arr と整数 k が与えられたとき、配列全体の GCD(最大公約数)を k の倍数に一致させるために必要な最小の操作回数を求めます。ここでいう「操作」とは、任意の要素の値を 1 増やす、または 1 減らすことを指します。

例として、配列が {4, 5, 6}、k = 5 の場合を考えてみます。4 を 1 増やして 5 にし、6 を 1 減らして 5 にすれば、すべての要素が 5 の倍数になり、GCD も 5 となります。このとき必要な操作回数は 2 回です。

アルゴリズムの手順

配列の GCD を k の倍数にするには、すべての要素を k の倍数に揃える必要があります。以下の手順に従うことで答えを求められます。

  • 配列内のすべての要素 e に対して、手順2と3を実行する
  • e が 1 ではなく、かつ e > k の場合:result に min(e mod k, k − e mod k) を加算する(余りをもとに、切り上げと切り下げの近い方を選択)
  • それ以外の場合:result に k − e を加算する(要素を k まで引き上げる)
  • 最終的な result を返す

C++による実装例

#include <iostream>
using namespace std;
int countMinOp(int arr[], int n, int k) {
    int result = 0;
    for (int i = 0; i < n; ++i) {
        if (arr[i] != 1 && arr[i] > k) {
            result = result + min(arr[i] % k, k - arr[i] % k);
        } else {
            result = result + k - arr[i];
        }
    }
    return result;
}
int main() {
    int arr[] = { 4, 5, 6 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int k = 5;
    cout << "Minimum operation required: " << countMinOp(arr, n, k);
}

出力

Minimum operation required: 2

処理のポイント

このアルゴリズムでは、各要素ごとに「最も近い k の倍数」までの距離を計算しています。要素が k より大きい場合は、剰余 (e mod k) を利用することで、切り上げた場合と切り下げた場合のどちらが近いかを 1 回の計算で判定できます。一方、要素が k 以下の場合は k まで引き上げるほかに選択肢がないため、単純に差分を加算します。

全体の計算量は O(n) であり、要素数が多い配列でも高速に動作するのが特徴です。貪欲法的なアプローチにより、各要素の最小操作の総和がそのまま答えになる点も理解しておきましょう。

  1. 【C++】配列を互いに素な配列に変換するための最小挿入回数を求める方法

    問題の概要 今回は、与えられた配列を互いに素な配列(コプライム配列)に変換するために必要な最小の挿入回数を求める、興味深い問題を取り上げます。互いに素な配列とは、隣り合う任意の2つの要素の最大公約数(GCD)が必ず1になる配列のことです。この記事では、必要な挿入回数に加えて、変換後の配列そのものも出力します。 例として、{5, 10, 20} という配列を考えてみましょう。この配列は隣接要素同士のGCDが5や10となるため、互いに素な配列ではありません。しかし、5と10の間、そして10と20の間にそれぞれ「1」を挿入すれば、{5, 1, 10, 1, 20} となり、すべての隣接ペアのGCD

  2. C++で配列の全要素を同じ値にするための最小削除操作数を求めるアルゴリズム

    問題概要n個の要素からなる配列が与えられます。要素には重複が含まれる場合があります。この配列から任意の数の要素を削除できるとき、すべての要素を同じ値にするために必要な最小の削除数を求めるのが課題です。例として、次の配列を考えてみましょう。arr[] = {10, 8, 10, 7, 10, -1, -4, 12}この場合、最も多く出現している「10」以外の5つの要素を削除すれば、配列の全要素を10で統一できます。つまり、答えは5回の削除となります。解法の考え方この問題の鍵となるのは、「削除する量を最小化する = 残す要素の数を最大化する」という発想です。全要素を同じ値にするためには、必ずどれか