C++でnを表すために必要なバイナリデシマルの最小個数を求めるプログラム
問題の概要
ある正整数 n が与えられます。バイナリデシマル(binary decimal)とは、10進表記におけるすべての桁が 0 または 1 のみで構成されている正整数のことです。たとえば、1001(千一)はバイナリデシマルですが、1021 は 2 という桁を含むため該当しません。
この問題では、与えられた数 n を、いくつかのバイナリデシマル(同じ数を何度使っても構いません)の和として表現することを考えます。その際に必要となるバイナリデシマルの最小個数を求めるのが目的です。
たとえば、入力が n = 121 の場合、出力は 2 になります。これは、121 を 110 + 11 または 111 + 10 という2つのバイナリデシマルの和で表せるためです。
解法の考え方
この問題の答えは、n の各桁の数字のうち最大のものになります。その理由は以下の通りです。
- 1つのバイナリデシマルは、どの桁に対しても最大で 1 しか加算できません。
- したがって、n の中で最も大きい桁の値 d を実現するには、少なくとも d 個のバイナリデシマルが必要です。
- 逆に d 個あれば、各桁の値をちょうど組み合わせて表現できるため、d 個で必ず足りります。
つまり、n を 1 桁ずつ走査して最大の桁を求めるだけで答えが得られます。
アルゴリズムの手順
ans := -1
while n > 0, do:
ans := maximum of ans and (n mod 10)
n := n / 10
return ansC++での実装例
理解を深めるために、以下の実装例を見てみましょう。
#include <bits/stdc++.h>
using namespace std;
int solve(int n) {
int ans = -1;
while (n > 0) {
ans = max(ans, n % 10);
n /= 10;
}
return ans;
}
int main() {
int n = 121;
cout << solve(n) << endl;
}入力
121
出力
2
計算量
このアルゴリズムの時間計算量は、n の桁数に比例する O(log10 n) であり、空間計算量は O(1) です。追加のデータ構造も不要で、非常にシンプルかつ効率的な解法となっています。
-
【C++】バイナリ行列をすべて0に変換するための最小操作回数を求めるプログラム
問題概要0と1のみから構成されるバイナリ行列が与えられます。使用できる操作は「任意の1つのセルを選び、そのセル自身と上下左右の隣接するセル(存在する場合のみ)をすべて反転(0→1、1→0)する」というものです。この操作を繰り返して行列の全要素を0にするために必要な最小操作回数を求めてください。どのように操作してもすべて0にできない場合は -1 を返します。入力例{{0, 0}, {1, 0}}これは次のような2×2の行列です。0010出力3この場合、必要な操作回数は3回となります。解法のアプローチこの問題は、行列の状態をビットマスク(整数)として表現し、幅優先探索(BFS)で最短操作回数を求め
-
C++で8進数を2進数に変換するプログラムの書き方【サンプルコード付き】
コンピュータシステムにおいて、2進数は2を基数とする記数法(二進法)で表現され、8進数は8を基数とする記数法(八進法)で表現されます。2進数は0と1のみを使用するのに対し、8進数は0から7までの数字を使用します。 2進数とそれに対応する8進数の例は以下の通りです。 2進数8進数 0110115 001015 1011026 0101012 以下に、8進数を2進数に変換するC++プログラムを示します。 サンプルプログラム #include <iostream> #include <cmath> using namespace std; int OctalToBi