C++である整数の各桁を並べ替えて作れる最大の数を求めるアルゴリズム
問題概要
n桁の整数が与えられたとき、その数を構成するすべての桁の数字を使って作成できる最大の数を求めることを考えます。例えば、与えられた数が 339625 の場合、各桁を並べ替えることで作れる最大の数は 965332 となります。
解決のアプローチ
この問題は、各桁の数字を降順(非増加順)にソートして出力するだけで簡単に解くことができます。しかし、ここではさらに効率的な方法を紹介します。
具体的には、サイズ10の配列を用意して各数字(0〜9)の出現頻度を記録します。その後、9から0へと順番に走査しながら、出現回数に応じて数字を配置していくことで、最大の数を効率よく構築できます。この手法の時間計算量は O(n) となり、一般的なソートアルゴリズムの O(n log n) よりも高速に動作します。
C++での実装例
#include <iostream>
#include <string>
using namespace std;
int maxNumFromNum(int num) {
int freq[10] = {0};
string str = to_string(num);
for (int i = 0; i < str.length(); i++)
freq[str[i] - '0']++;
int res = 0, mul = 1;
for (int i = 0; i <= 9; i++) {
while (freq[i] > 0) {
res = res + (i * mul);
freq[i]--;
mul = mul * 10;
}
}
return res;
}
int main() {
int num = 339625;
cout << "Maximum number: " << maxNumFromNum(num);
}コードのポイント
- freq 配列: 各数字(0〜9)の出現回数をカウントします。
- res と mul: 小さい数字から順に加算し、mul を10倍ずつ増やすことで、大きい数字が自然と上位の桁に配置される仕組みです。
- 計算量: 桁数を n とすると、時間計算量は O(n)、空間計算量は固定サイズの配列のみ使用するため O(1) です。
実行結果
Maximum number: 965332
まとめ
このように、度数分布配列(バケット)を活用することで、桁の並べ替えによる最大数の生成を線形時間で効率的に求められます。桁数が多い場合や同じ処理を繰り返し実行するケースで特に有効なテクニックなので、ぜひ覚えておきましょう。
-
C++でN個のセグメントを使って7セグメントディスプレイに表示できる最大の数を求める方法
問題の概要 この記事では、7セグメントディスプレイに対してN個のセグメントを使用したときに、表示できる最大の数を求める方法を解説します。 まず、具体例を使って何をすべきかを確認しましょう。 入力 − N=5 出力 − 71 説明 − この場合、最大の数は7セグメントディスプレイ上で次のように表示されます。 入力 − N=6 出力 − 111 アルゴリズムのアプローチ この問題は、次の3つの場合に分けて考えることができます。 ケース1 −Nが0または1の場合、どの数字も表示できません。 ケース2 −Nが奇数の場合です。奇数個のセグメントで表示できる数字は2、3、5、7、8であり、その中で最
-
C++で「x + 桁の合計 = n」を満たす数xを見つける方法
この記事では、ある整数 n が与えられたとき、「x + x の各桁の合計 = n」という条件を満たす数 x を求める問題を解説します。例として、n = 21 の場合を考えてみましょう。このとき答えは x = 15 となります。なぜなら、15 の各桁の合計は 1 + 5 = 6 であり、15 + 6 = 21 となって、与えられた n と一致するからです。解き方のアプローチこの問題はシンプルな方法で解くことができます。1 から n まで順番に数を調べていき、それぞれの数について「その数自身 + 各桁の合計」が n と等しくなるかどうかを確認します。条件を満たす数が見つかった時点で処理を終了し、そ