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

C++で配列内の最小XOR値ペアを求める方法

問題概要

整数の配列が与えられたとき、配列内のペアの中でXOR値が最小となるペアを見つける問題です。

例えば、配列 arr[] = {10, 20, 30, 40} が与えられた場合を考えてみましょう。各ペアのXOR値を計算すると以下のようになります。

(10 ^ 20) = 30
(10 ^ 30) = 20
(10 ^ 40) = 34
(20 ^ 30) = 10
(20 ^ 40) = 60
(30 ^ 40) = 54

この結果から、最小のXOR値は 10 であり、これはペア「20 と 30」に対応することがわかります。

アルゴリズム

最もシンプルなアプローチは、全探索(ブルートフォース)です。

  • 配列から取り得るすべてのペアを生成する
  • 各ペアのXOR値を計算する
  • 最小のXOR値を返す

この方法の計算量は O(n²) となります。n が小さい場合は十分実用的ですが、配列サイズが大きくなると非効率になります。

C++での実装例

以下は、全探索を用いたC++の実装コードです。

#include <bits/stdc++.h>
using namespace std;

int getMinValue(int *arr, int n) {
    int minValue = INT_MAX;
    for (int i = 0; i < n; ++i) {
        for (int j = i + 1; j < n; ++j) {
            minValue = min(minValue, arr[i] ^ arr[j]);
        }
    }
    return minValue;
}

int main() {
    int arr[] = {10, 20, 30, 40};
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << "Minimum value = " << getMinValue(arr, n) << endl;
    return 0;
}

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

出力結果

Minimum value = 10

補足:より効率的なアプローチ

配列をあらかじめソートしておくと、最小のXOR値は「ソート後の配列で隣接する要素のペア」の中に必ず存在するという性質があります。この性質を利用すると、計算量を O(n log n) まで削減できます。さらに、ビットごとに要素を分類するTrie(トライ木)を用いた手法では、O(n × ビット長) で解くことも可能です。大規模なデータを扱う場合は、これらの最適化手法の活用を検討するとよいでしょう。

  1. C++で解くジョブスケジュールの最小難易度問題

    問題概要d日間でタスクのリストをスケジューリングすることを考えます。タスクには依存関係があり、i番目のタスクに取り掛かるためには、0 <= j < i を満たすすべてのタスク j を先に完了させておく必要があります。さらに、毎日最低1つはタスクを完了させなければなりません。スケジュール全体の難易度は、d日間の各日の難易度の合計として定義され、ある日の難易度は、その日に完了したタスクの中で最も高い難易度の値となります。ここで、整数型配列 taskDifficulty と整数 d が与えられます。i番目のタスクの難易度は taskDifficulty[i] です。スケジュール全体の難易

  2. C++で最大ヒープから最小値の要素を見つける方法

    問題の概要最大ヒープ(max heap)の中から、最も小さい値を持つ要素を探す方法を解説します。以下のような最大ヒープを例に考えてみましょう。最大ヒープでは、親ノードの値は必ずその子ノードの値以上になります。この性質により、最小値は必ず葉ノード(leaf node)のいずれかに存在すると結論できます。ヒープが n 個のノードを含む場合、葉ノードの数は ceil(n/2) 個になります。また、最大ヒープは完全二分木であるため、配列として表現することができます。このとき、最初の葉ノードは floor(n/2) のインデックス以降に配置されます。上記の例では、最初の葉ノードはインデックス 5 に存在