【C++】ビット単位ORがnと等しくなる最大の集合を求める方法
このチュートリアルでは、与えられた数値 n に対して、ビット単位OR(bitwise OR)の結果が n と等しくなる最大の集合を見つけるプログラムを C++ で作成します。
問題の考え方
ある整数 i と n のビット単位ORが n と等しくなるためには、i のセットされているビットがすべて n のセットされているビットに含まれている必要があります。つまり、i は n のビットパターンの「部分集合」であればよいことになります。
解法の手順
- 数値 n を初期化します。
- 0 から n まで繰り返すループを作成します。
- もし
i | nの結果が n と等しければ、i を結果の集合に追加します。
- もし
- 最後に結果を出力します。
サンプルコード
それでは、実際のコードを見てみましょう。
#include <bits/stdc++.h>
using namespace std;
void printBitWiseOrSet(int n) {
vector<int> v;
for (int i = 0; i <= n; i++) {
if ((i | n) == n) {
v.push_back(i);
}
}
for (int i = 0; i < v.size(); i++) {
cout << v[i] << ' ';
}
cout << endl;
}
int main() {
int n = 7;
printBitWiseOrSet(n);
return 0;
}実行結果
上記のコードを実行すると、次のような出力が得られます。
0 1 2 3 4 5 6 7
解説
n = 7 の場合、7 は2進数で 111 と表されます。したがって、0 から 7 までのすべての整数は 7 のビットパターンの部分集合となり、i | 7 == 7 が常に成立します。そのため、結果として 0 から 7 までのすべての数値が出力されます。
一方、例えば n = 5(2進数で 101)の場合、条件を満たすのは 0, 1, 4, 5 のみとなります。このように、n のビット構成によって結果の集合の大きさが決まります。
まとめ
このアルゴリズムの計算量は O(n) であり、シンプルな線形探索で問題を解くことができます。ビット演算の性質を理解する良い練習問題なので、ぜひさまざまな n の値で試してみてください。
このチュートリアルについて質問がある場合は、コメント欄でお気軽にお尋ねください。
-
C++でマンハッタン距離と等しい距離を持つパスの数を求める方法
2次元座標系上の2つの点 (x1, y1) と (x2, y2) を表す変数 x1、x2、y1、y2 が与えられます。この記事の目的は、これら2点間のマンハッタン距離と等しい距離を持つすべてのパスの総数を求めることです。 マンハッタン距離とは 2点 (x1, y1) と (x2, y2) の間のマンハッタン距離は、次の式で定義されます。 MD = |x1 − x2| + |y1 − y2| ここで、A = |x1 − x2|、B = |y1 − y2| とおきます。 マンハッタン距離と等しい距離を持つすべてのパスは、合計 (A + B) 本の移動で構成されます。そのうち A 本が水平方向の移動
-
C++で要素の積とLCMが一致する最長部分配列を求めるアルゴリズム
問題概要配列 A が与えられたとき、「その部分配列の最小公倍数(LCM)」と「部分配列内の要素の積」が一致するような部分配列の中で、最も長いものの長さを求めます。条件を満たす部分配列が存在しない場合は -1 を返します。例として、配列が {6, 10, 21} である場合を考えてみましょう。部分配列 {10, 21} に注目すると、その最小公倍数は 210、要素の積も 210 となり、両者が一致します。このため、答えは 2 となります。解き方のアプローチこの問題へのアプローチは非常にシンプルです。長さ 2 以上のすべての部分配列を網羅的にチェックし、条件を満たすものが見つかるたびに、これまでの