C++で整数を2の累乗の和で表す方法 ― 指数を求めるアルゴリズムを解説
問題の概要
この問題では、整数 N が与えられます。求めるのは、N を2の累乗の和として表したときに使われる指数(べき乗の部分)を出力することです。
入出力の例
入力: 17
出力: 0, 4
説明: 17 = 24 + 20 = 16 + 1
解き方のアプローチ
この問題を解くには、与えられた数を 2で再帰的に割っていく 方法が有効です。この手法を使えば、任意の整数を必ず2の累乗の和として表現できます。
実は、この処理は 数を2進数に変換する手順とまったく同じ です。2進数表現で「1」が立っている桁の位置が、そのまま2の累乗の指数に対応します。たとえば 17 を2進数で表すと「10001」となり、0桁目と4桁目が1なので、答えは「0, 4」となります。
C++による実装例
以下は、この考え方を実装したサンプルプログラムです。
#include <bits/stdc++.h>
using namespace std;
void sumPower(long int x) {
vector<long int> powers;
// 2で割り続けて各桁(0か1)を取り出す
while (x > 0) {
powers.push_back(x % 2);
x = x / 2;
}
// 1が立っている桁の位置(=指数)を出力
for (int i = 0; i < powers.size(); i++) {
if (powers[i] == 1) {
cout << i;
if (i != powers.size() - 1)
cout << ", ";
}
}
cout << endl;
}
int main() {
int number = 23342;
cout << "Powers of 2 that sum upto " << number << " are : ";
sumPower(number);
return 0;
}
コードのポイント
sumPower関数では、まず引数 x を2で割った余りを順に vector に格納し、2進数の各桁を求めています。その後、値が「1」になっている桁のインデックスを出力します。このインデックスこそが、2の何乗に相当するかを示す指数です。
実行結果
Powers of 2 that sum upto 23342 are : 1, 2, 3, 5, 8, 9, 11, 12, 14
この結果は、23342 = 214 + 212 + 211 + 29 + 28 + 25 + 23 + 22 + 21 と表せることを意味しています。
まとめ
整数を2の累乗の和に分解する問題は、2進数変換の知識があればシンプルに解けます。計算量は数のビット長に比例する O(log N) で、非常に効率的です。ビット演算に慣れるための練習問題としても最適なので、ぜひ自分でも実装してみてください。
-
C++で数値を別の数の累乗の和・差として表現できるか判定する方法
問題概要本記事では、ある数値を別の数値の累乗の組み合わせで表現できるかどうかを判定する問題について解説します。2つの整数 x と y が与えられ、x の各累乗はそれぞれ一度しか使用できないという条件のもとで、y を x の累乗の和と差で表せるかを判定します。入力: x = 4, y = 11 出力: true 説明: 4^2 − 4^1 − 4^0 = 11 となるため、y は x の累乗で表現できます。 入力: x = 2, y = 19 出力: true 説明: 2^4 + 2^1 + 2^0 = 19 となるため、y は x の累乗で表現できます。 入力: x = 3, y = 14
-
C++で五胞体数(ペンタトープ数)を求める方法
五胞体数とは? 五胞体数(ペンタトープ数)は、パスカルの三角形の第5の対角線上に現れる数列として知られています。この数列を定義するには、パスカルの三角形に少なくとも5つの数が必要となるため、数列の最初の数はパスカルの三角形の第4行である 1 4 6 4 1 から始まります。 本チュートリアルでは、n番目の五胞体数を求める方法を解説します。まずは具体的な例を見てみましょう。 入力 : 1出力 : 1入力 : 4出力 : 35 以下の図から出力を確認できます。 この問題は数列に関するものなので、解法ではまず数列のパターンを見つけることから始めます。 解法のアプローチ このプログラムでは、数列の