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

C++で配列の数字から作る2つの数値の合計を最小化する方法


問題の概要

0から9までの値を含む数字の配列が与えられます。この問題では、配列内のすべての数字を使って2つの数値を作り、その合計が最小になるようにすることが求められます。重要な制約として、与えられた配列のすべての数字を必ず使用しなければなりません。

入力配列が {7, 5, 1, 3, 2, 4} の場合、最小合計は 382 となります。これは、135247 という2つの数値を作成できるためです(135 + 247 = 382)。

アルゴリズムの考え方

この問題は貪欲法(グリーディ法)で解くことができます。合計を最小にするには、小さい桁の数字ほど大きな位(上位の桁)に配置するのが最適だからです。手順は以下の通りです。

  • 配列を昇順にソートします。
  • ソート済みの配列から、偶数インデックスと奇数インデックスの数字を交互に取り出し、それぞれ別の数値を構成します。これにより、小さい数字が2つの数値の上位の桁に均等に分散されます。

C++での実装例

#include <bits/stdc++.h>
using namespace std;
int getMinSum(int *arr, int n) {
    sort(arr, arr + n);
    int a = 0;
    int b = 0;
    for (int i = 0; i < n; ++i) {
        if (i % 2 == 0) {
            a = a * 10 + arr[i];
        } else {
            b = b * 10 + arr[i];
        }
    }
    return a + b;
}
int main() {
    int arr[] = {7, 5, 1, 3, 2, 4};
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << "Minimum sum = " << getMinSum(arr, n) << endl;
    return 0;
}

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

実行結果

Minimum sum = 382

計算量について

このアルゴリズムの時間計算量は、ソート処理が支配的となるため O(n log n) です。空間計算量は追加の配列を使用しないため O(1) となります。数字を交互に振り分けることで、両方の数値の桁数の差が最大1桁に抑えられ、結果として合計が最小になります。


  1. C++で桁の合計に基づいて数値をソートする方法

    この記事では、各数値の「桁の合計(各桁の数字を足した値)」に基づいて数値を並べ替える方法を解説します。桁の合計が小さい数値ほど先頭に配置され、合計が大きい数値ほど後ろに配置されます。ソートの例例として、次のようなデータを考えてみましょう。data = {14, 129, 501, 23, 0, 145}このデータを桁の合計順にソートすると、以下のようになります。0 → 桁の合計は 014 → 桁の合計は 1 + 4 = 523 → 桁の合計は 2 + 3 = 5501 → 桁の合計は 5 + 0 + 1 = 6145 → 桁の合計は 1 + 4 + 5 = 10129 → 桁の合計は 1 +

  2. C++の配列パズル:減算演算子を使わずに「自分以外の要素の合計」を求める方法

    今回は、配列に関する興味深い問題を紹介します。n個の要素を持つ配列が与えられ、それをもとに同じくn個の要素を持つ別の配列を作成します。ただし、新しい配列のi番目には、元の配列のi番目の要素を除いたすべての要素の合計を格納します。さらに重要な制約として、減算演算子(-)を使用してはいけないという条件が課されています。 問題のポイント もし減算が使えるのであれば、話は簡単です。まず全要素の合計を求めておき、そこからi番目の要素を引いた値を新しい配列のi番目に格納すればよいだけです。しかし、この問題では減算が禁止されているため、別のアプローチが必要になります。 そこで、各位置i(0〜n-1)について