C++でXORが0になる配列内のペアの数を求める方法
n個の要素を含む配列が与えられたとき、XOR(排他的論理和)の計算結果が0になるペアの数を求めることを考えます。ペア(x, y)のXORが0になるのは、x = y が成り立つ場合、すなわち2つの値が等しいときだけです。これは「同じ数値同士のXORは必ず0になる」というビット演算の基本的な性質によるものです。
解法のアプローチ
この問題は、次の手順で解くことができます。
- まず、配列を昇順にソートします。
- ソート後は同じ値どうしが隣り合って並ぶため、連続する2つの要素を比較し、等しければカウントを1つ増やします。
- すべての要素が同じ値である場合、末尾側のペアがカウントから漏れる可能性があります。そこで、配列の先頭と末尾の要素が等しいかどうかを確認し、等しければカウントをさらに1つ増やします。
サンプルコード
#include<iostream>
#include<algorithm>
using namespace std;
int countPairs(int arr[], int n) {
int count = 0;
sort(arr, arr+n);
for(int i = 0; i<n - 1; i++){
if(arr[i] == arr[i+1]){
count++;
}
}
if(arr[0] == arr[n-1])
count++;
return count;
}
int main() {
int arr[] = {1, 2, 1, 2, 4};
int n = sizeof(arr)/sizeof(arr[0]);
cout << "Number of pairs: " << countPairs(arr, n);
}実行結果
Number of pairs: 2
コードの解説
サンプル配列 {1, 2, 1, 2, 4} をソートすると {1, 1, 2, 2, 4} になります。隣接する要素を順に比較すると、「1と1」「2と2」の2組が等しいため、カウントは2になります。先頭と末尾の要素(1と4)は異なるため、追加のカウントは発生せず、最終的な出力は「Number of pairs: 2」となります。
補足: すべての組み合わせを正確に数えたい場合
上記の方法は、隣接する等しい要素のペアを数えるアプローチです。同じ値が3回以上出現するケースで、すべてのペアの組み合わせ(同じ値がk個あるとき、選び方は k×(k-1)/2 通り)を正確に求めたい場合は、ハッシュマップなどで各値の出現回数を集計し、k×(k-1)/2 を合計する方法が確実です。この方法ならソートが不要となり、計算量をO(n)に抑えることができます。
-
C++を使って「数x + xの桁の合計 = n」となる数xを求める方法
ここでは、ある数nが与えられたとき、「数xとその桁の合計を足した値がnと等しくなる」ようなxを求める問題を扱います。例えば、nが21の場合、答えはx = 15となります。15の桁の合計は1 + 5 = 6なので、15 + 6 = 21 = nとなり、条件を満たすからです。この問題を解くには、シンプルなアプローチが有効です。0からnまでの数を順番に調べていき、各数値について「その数 + 桁の合計」がnと一致するかどうかを確認します。一致する数が見つかった時点でその値を返し、最後まで見つからなければ-1を返します。サンプルコード#include<iostream> using name
-
C++で配列内の a % b = k を満たすすべてのペア(a, b)を検索する方法
問題の概要配列 A が与えられたとき、その中から a % b = k を満たすすべてのペア(a, b)を見つけることを考えます。たとえば、配列 A = [2, 3, 4, 5, 7]、k = 3 の場合、条件を満たすペアは (7, 4)、(3, 4)、(3, 5)、(3, 7) となります。ここで注意したいのは、(a, b) が順序付きペアであるという点です。つまり (3, 4) と (4, 3) は別々の候補として扱われ、それぞれ剰余演算の結果が k と一致するかどうかが個別に判定されます。解法のアプローチこの問題は、ブルートフォース(総当たり)法によって解くことができます。手順は以下のとお