C++で配列から4つの要素を選んだ最大積を求める方法
n個の整数が格納された配列が与えられたとき、その中から4つの要素を選んで作れる積(クアドラプル)の最大値を求める問題について解説します。
例えば、配列が [3, 5, 20, 6, 10] の場合、最大積は 6000 となり、このとき選ばれる4つの要素は 10, 5, 6, 20 です。
解法のアプローチ
この問題は、配列をソートすることで効率的に解くことができます。最大積の候補として考えられるのは以下の3パターンだけです。
- 配列を昇順にソートする
- x = 最後の4要素(最も大きい4つ)の積とする
- y = 最初の4要素(最も小さい4つ)の積とする
- z = 最初の2要素と最後の2要素の積とする
x、y、z のうち最大のものを返せば答えになります。
なぜ3パターンだけで十分なのか
負の数が含まれる場合に注意が必要です。負の数同士を掛けると正になるため、「最も小さい(絶対値の大きい負の)2つ」と「最も大きい2つ」を掛け合わせた組み合わせが最大になる可能性があります。上記の3パターンを比較すれば、正の数のみの場合も負の数が混在する場合もすべてカバーできます。
C++での実装例
#include<iostream>
#include<algorithm>
using namespace std;
int maxQuadProduct(int arr[], int n) {
if (n < 4)
return -1;
sort(arr, arr + n);
int last_four = arr[n - 1] * arr[n - 2] * arr[n - 3] * arr[n - 4];
int first_four = arr[0] * arr[1] * arr[2] * arr[3];
int two_first_last = arr[0] * arr[1] * arr[n - 1] * arr[n - 2];
return max(last_four, max(first_four, two_first_last));
}
int main() {
int arr[] = { -10, -3, 5, 6, -20 };
int n = sizeof(arr) / sizeof(arr[0]);
int maximum_val = maxQuadProduct(arr, n);
if (maximum_val == -1)
cout << "No Quadruple Exists";
else
cout << "Maximum product is " << maximum_val;
}実行結果
Maximum product is 6000
コードのポイント
- 要素数が4未満の場合はクアドラプルが存在しないため、
-1を返してエラー扱いにしています。 std::sortによるソートの計算量は O(n log n) であり、全組み合わせを調べる O(n⁴) の総当たり方式より大幅に効率的です。- サンプル入力
{ -10, -3, 5, 6, -20 }では、最初の2要素(-20 × -10 = 200)と最後の2要素(5 × 6 = 30)の積である 200 × 30 = 6000 が最大となり、z のパターンが採用される好例です。
-
C++で配列内の数値の頻度(出現回数)を求める方法
配列に n 個の異なる要素が格納されているとします。この配列の中から、特定の要素が何回出現するか(頻度)を調べたい場合があります。例えば、配列 A = [5, 12, 26, 5, 3, 4, 15, 5, 8, 4] の中で「5」の頻度を調べると、答えは 3 になります。アルゴリズムの考え方この問題は、次の手順で解くことができます。1. 配列を左端から順に走査します。2. 現在の要素が調べたい数値と一致したら、カウンターを1つ増やします。3. 一致しない場合は、そのまま次の要素へ進みます。4. 配列の最後まで走査したら、カウンターの値が頻度となります。このアルゴリズムの計算量は O(n) で
-
グラフの最大カットを求めるC++プログラム ― 辺連結性と橋(ブリッジ)の検出
本記事では、グラフの最大カットを求める問題に関連して、グラフの辺連結性を調べるC++プログラムを紹介します。ここで扱うのは「橋(ブリッジ)」と呼ばれる特別な辺の検出です。 橋(ブリッジ)とは何か? 無向グラフにおける橋(ブリッジ)とは、その辺を取り除いた瞬間にグラフが非連結になってしまう辺のことです。言い換えれば、橋を1本取り除くだけで、グラフの連結成分の数が増加します。この性質を利用すると、ネットワークの中で特に脆弱な箇所(切断されやすいリンク)を特定できます。 アルゴリズムの考え方と擬似コード 橋の検出には、深さ優先探索(DFS)を用いるのが定番です。各頂点に対して「発見時刻(dis)」と