C++で4つの配列からXORがxと等しくなる4つ組(クワドループル)をすべて数える方法
このチュートリアルでは、4つの配列から1つずつ要素を選んだとき、そのXOR(排他的論理和)が指定した値xと等しくなる組み合わせ(4つ組)の個数を求めるプログラムについて解説します。
具体的には、4つの配列と値xが与えられ、各配列から1つずつ要素を選んで作れるすべての組み合わせの中から、XORの結果がxと一致するものを数えるのが目的です。
解き方のアプローチ
最もシンプルな方法は、4重のループを使った総当たり(ブルートフォース)です。4つの配列から選べる要素の組み合わせをすべて列挙し、それぞれについてXORを計算します。結果がxと等しければカウントを1つ増やし、最終的なカウントを答えとして返します。
サンプルコード
#include<bits/stdc++.h>
using namespace std;
// XORがxと等しくなる4つ組の個数を数える関数
int count_quad(int a[], int b[], int c[], int d[],
int x, int n){
int count = 0;
for (int i = 0 ; i < n ; i++)
for (int j = 0 ; j < n ; j++)
for (int k = 0 ; k < n ; k++)
for (int l = 0 ; l < n ; l++)
if ((a[i] ^ b[j] ^ c[k] ^ d[l]) == x)
count++;
return count;
}
int main(){
int x = 3;
int a[] = {0, 1};
int b[] = {2, 0};
int c[] = {0, 1};
int d[] = {0, 1};
int n = sizeof(a)/sizeof(a[0]);
cout << count_quad(a, b, c, d, x, n) << endl;
return 0;
}出力
4
コードの解説
上記の例では、配列a、b、c、dから1つずつ要素を選んだとき、XORが3になる組み合わせは次の4通りです。
- (0, 2, 0, 1) → 0 ^ 2 ^ 0 ^ 1 = 3
- (0, 2, 1, 0) → 0 ^ 2 ^ 1 ^ 0 = 3
- (1, 2, 0, 0) → 1 ^ 2 ^ 0 ^ 0 = 3
- (1, 2, 1, 1) → 1 ^ 2 ^ 1 ^ 1 = 3
したがって、プログラムは4を出力します。
計算量と高速化のヒント
この総当たり法の時間計算量はO(n⁴)であり、配列のサイズが大きくなると実行時間が急激に増加します。実務では、ミート・イン・ザ・ミドル(Meet in the Middle)と呼ばれる手法を使うと効率化できます。まず配列aとbのすべてのペアのXORを計算してハッシュマップに記録し、次に配列cとdのペアのXORごとに「x ^ (c[k] ^ d[l])」という値がマップ内にいくつ存在するかを調べればよいのです。これにより、計算量をO(n²)まで大幅に削減できます。
まずは本記事のシンプルな実装でロジックを理解し、データ规模が大きいケースでは高速化手法の導入を検討するとよいでしょう。
-
C++でn XOR (n+1) = kを満たす最小のnを求める方法
問題の概要正の整数 k が与えられたとき、n XOR (n+1) の計算結果が k と等しくなるような正の整数 n を求めることを考えます。例えば、k = 7(2進数で 111)の場合、答えは 3 になります。3 は 2進数で 011、3 + 1 = 4 は 100 と表され、011 XOR 100 = 111(10進数で 7)となるためです。アルゴリズムの考え方この問題は、n の偶奇によって2つの場合に分けて考えることができます。n が偶数の場合n が偶数であれば、n の最下位ビットは 0、n + 1 の最下位ビットは 1 となり、それ以外の上位ビットはすべて同一です。したがって、XOR の
-
C++でXORが0になる配列内のペアの数を求める方法
n個の要素を含む配列が与えられたとき、XOR(排他的論理和)の計算結果が0になるペアの数を求めることを考えます。ペア(x, y)のXORが0になるのは、x = y が成り立つ場合、すなわち2つの値が等しいときだけです。これは「同じ数値同士のXORは必ず0になる」というビット演算の基本的な性質によるものです。解法のアプローチこの問題は、次の手順で解くことができます。まず、配列を昇順にソートします。ソート後は同じ値どうしが隣り合って並ぶため、連続する2つの要素を比較し、等しければカウントを1つ増やします。すべての要素が同じ値である場合、末尾側のペアがカウントから漏れる可能性があります。そこで、配列