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

C++で数値がBleak(ブリーク)かどうかを判定する方法

本記事では、ある数値がBleak(ブリーク)であるかどうかを判定する方法を解説します。Bleak数とは、任意の非負整数 x に対して、xx のセットビット数(2進表現で1となっているビットの個数)との和がその数に一致しない、すなわち x + set_bit_count(x) ≠ n が成り立つような数のことです。

言い換えれば、n = x + セットビット数(x) を満たす非負整数 x がひとつも存在しない場合、n は Bleak 数であるといえます。

判定の考え方

判定のアプローチは非常にシンプルです。1 から n-1 までの各整数 i について「i + i のセットビット数」を計算し、その結果が n と一致するかどうかを順番に確認します。一致する i が見つかれば n は Bleak 数ではなく、最後まで見つからなければ n は Bleak 数であると判定できます。

具体例を挙げると、3 は 2 + 1(2は2進数で「10」なのでセットビット数は1)と表せるため Bleak 数ではありません。一方、4 はどの整数とそのセットビット数の和としても表せないため、Bleak 数となります。

サンプルコード

セットビット数の計算には、Brian Kernighan のアルゴリズム(x &= (x - 1) を繰り返して1を消去していく手法)を使用しています。この方法により、セットビット数だけループが回るため効率的にカウントできます。

#include <iostream>
using namespace std;

// セットビット数(1になっているビットの個数)を数える関数
int set_bit_count(int x) {
    unsigned int bit_count = 0;
    while (x != 0) {
        x &= (x - 1); // 最下位の1ビットを消去
        bit_count++;
    }
    return bit_count;
}

// n が Bleak 数かどうかを判定する関数
bool isBleakNumber(int n) {
    for (int i = 1; i < n; i++) {
        if (i + set_bit_count(i) == n)
            return false; // 表せる組み合わせが存在 → Bleakではない
    }
    return true; // 見つからなかった → Bleak数
}

int main() {
    isBleakNumber(3) ? cout << "Yes\n" : cout << "No\n";
    isBleakNumber(4) ? cout << "Yes\n" : cout << "No\n";
}

実行結果

No
Yes

処理の流れと計算量

このプログラムでは、まず set_bit_count() 関数が与えられた整数のセットビット数を返します。次に isBleakNumber() 関数が 1 から n-1 までの候補をすべて調べ、条件を満たすものがあれば false(Bleakではない)を返します。

計算量については、候補の探索に O(n)、各候補のセットビット数計算に O(log n) かかるため、全体の時間計算量は O(n log n) となります。小〜中規模の数値であれば十分実用的ですが、より大きな数値を扱う場合は探索範囲の工夫(セットビット数は log₂n 以下であるため、n - log₂n 以降のみを調べればよい)によって高速化することも可能です。

  1. C++でNが五角数(ペンタゴナル数)かどうかを判定するプログラム

    五角数とはある整数 N が与えられたとき、それが五角数(ペンタゴナル数)であるかどうかを判定するのが本記事の目的です。五角数とは、点を並べることで正五角形の形を描くことができる数のことです。これらの数は、五角形を構成する頂点や点として表現できます。五角数の例としては、次のような数列が挙げられます。1, 5, 12, 22, 35, 51, 70, 92 …五角数を判定する公式ある数が五角数かどうかは、以下の公式を利用して確認できます。p(n) = (3 × n² − n) / 2ここで、n は五角形を構成する点の個数を表します。この式から得られる値が順に 1, 5, 12, 22, 35… と

  2. アームストロング数を判定するC++プログラムの書き方と解説

    アームストロング数とはアームストロング数(Armstrong Number)とは、各桁の数字を「総桁数」乗した値の合計が、元の数そのものと等しくなる数のことです。例えば、153は3桁の数なので、各桁を3乗して足し合わせると元の数に戻ります。主なアームストロング数の例は以下の通りです。3 = 3^1 153 = 1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153 371 = 3^3 + 7^3 + 1^3 = 27 + 343 + 1 = 371 407 = 4^3 + 0^3 + 7^3 = 64 + 0 + 343 = 407この性質を利用すると、任意の整数がアームスト