【C++】配列内のすべてのトリプレット(3要素の組み合わせ)におけるXORの最大値を求める方法
この問題では、整数の配列が与えられます。求めるのは、配列から選んだ3つの要素(トリプレット)の組み合わせすべての中で、XOR(排他的論理和)の値が最大になるものです。
問題の例
具体的な例を使って問題を確認してみましょう。
入力: array = {5, 6, 1, 2}
出力: 6
説明:
考えられるすべてのトリプレットとそのXOR値: 5 ^ 6 ^ 1 = 2 5 ^ 6 ^ 2 = 1 5 ^ 1 ^ 2 = 6 6 ^ 1 ^ 2 = 5
この中で最も大きいXORの値は 6(5 ^ 1 ^ 2)となるため、答えは 6 になります。
解法のアプローチ
最も単純な方法は、考えられるすべてのトリプレットのXORを総当たりで計算し、その最大値を出力することです。しかし、配列の要素数が非常に大きい場合、この方法は計算量が膨大になり、実用的ではありません。
そこで、より効率的に最大XORを求めるために、次の手順でアルゴリズムを構成します。
- まず、配列内のすべてのペア(2要素)のXOR値を計算し、重複を除いてセット(set)に格納します。
- 次に、セットに含まれる各XOR値と、配列の各要素とのXORを計算します。
- 得られた値の中で最大のものを答えとして返します。
このようにペアのXORを事前にセットへまとめておくことで、同じXOR値の重複計算を避けることができ、素朴な全トリプレット走査よりも効率よく処理できます。
C++での実装例
上記の解法を実装したプログラムがこちらです。
#include <bits/stdc++.h>
using namespace std;
int MaxTripletXor(int n, int a[]) {
// すべてのペアのXOR値をセットに格納
set<int> XORpair;
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
XORpair.insert(a[i] ^ a[j]);
}
}
// セット内の各値と配列の各要素とのXORの最大値を求める
int maxXOR = 0;
for (auto i : XORpair) {
for (int j = 0; j < n; j++) {
maxXOR = max(maxXOR, i ^ a[j]);
}
}
return maxXOR;
}
int main() {
int matrix[] = {1, 2, 3, 5, 7};
int n = sizeof(matrix) / sizeof(matrix[0]);
cout << "The maximum XOR sum triplets is " << MaxTripletXor(n, matrix);
return 0;
}
実行結果
The maximum XOR sum triplets is 7
コードの解説
- XORpair(セット): 配列内の全ペア a[i] ^ a[j] の結果を格納します。std::set を使うことで、重複するXOR値が自動的に排除されます。
- 第2ループ: セット内の各値と配列の各要素をXORし、これまでの最大値(maxXOR)より大きければ更新します。
- 戻り値: 最終的な maxXOR が、すべてのトリプレットの中で最大のXOR値となります。
このサンプルでは配列 {1, 2, 3, 5, 7} を使用しており、最大のトリプレットXORとして 7 が出力されます。
-
C++で配列内のすべてのペアのXORの合計を求める方法
この問題では、n個の整数からなる配列 arr[] が与えられます。配列内のすべてのペアについてXORを計算し、その合計を求めるプログラムを作成することが課題です。問題を理解するための例入力: arr[] = {5, 1, 4} 出力: 10 説明: すべてのペアのXOR: 5 ^ 1 = 4 1 ^ 4 = 5 5 ^ 4 = 1 合計 = 4 + 5 + 1 = 10解法1: 全ペアを列挙する素朴なアプローチ最もシンプルな解き方は、ネストされたループを使って配列内のすべてのペアを列挙する方法です。各ペアのXORを計算し、それを順次合計に加算していきます。アルゴリズムsum = 0 で初期化
-
【C++】配列内のすべての素数の積を求める方法
整数型配列 arr[] が与えられたとき、その配列に含まれるすべての素数を見つけ出し、それらの積を計算するのが本記事のテーマです。素数とは、1とその数自身でしか割り切れない正の整数のことです。たとえば、2、3、5、7、11などが素数に該当します。それでは、次の配列を例に解を求めてみましょう。入力: arr[] = { 11, 20, 31, 4, 5, 6, 70 }出力: 1705説明: 配列内の素数は 11、31、5 の3つであり、その積は 11 × 31 × 5 = 1705 となります。入力: arr[] = { 1, 2, 3, 4, 5, 6, 7 }出力: 210説明: 配列内の