C++でx^1〜x^nの各値に含まれる数字の出現頻度配列を作成する方法
問題の概要
2つの整数 x と n が与えられたとき、x1, x2, …, xn の各値に出現する数字(0〜9)の頻度を格納した配列を作成することを考えます。
例えば、x = 15、n = 3 の場合を見てみましょう。x1 から xn までの値は以下のとおりです。
- 151 = 15
- 152 = 225
- 153 = 3375
これらの値に含まれる各数字の出現回数を集計すると、結果は [0, 1, 2, 2, 0, 3, 0, 1, 0, 0] となります。この配列の各要素は、インデックス0〜9に対応する数字が何回出現したかを表しています。
解決の手順
この問題は、以下の手順で解くことができます。
0〜9の数字の出現回数を格納するための頻度カウント配列を用意し、すべて0で初期化します。
x1 から xn までの各値について、桁を一つずつ取り出して調べ、対応するインデックスのカウントを1ずつ増やしていきます。
最後に、集計結果の配列を表示します。
C++での実装例
#include <iostream>
#include <cmath>
using namespace std;
void digitCount(double val, long arr[]) {
while ((long)val > 0) {
long digit = (long)val % 10;
arr[(int)digit]++;
val = (long)val / 10;
}
}
void generateFreqArray(int x, int n) {
long freq_count[10]={0};
for (int i = 1; i <= n; i++){
double val = pow((double)x, (double)i);
digitCount(val, freq_count);
}
cout << "[";
for (int i = 0; i <= 9; i++){
cout << freq_count[i] << " ";
}
cout << "\b]";
}
int main() {
int x = 15, n = 3;
cout << "The frequency array is: ";
generateFreqArray(x, n);
}
出力結果
The frequency array is: [0 1 2 2 0 3 0 1 0 0]
※ 出力メッセージは「頻度配列は次のとおりです」という意味です。
補足:実装上の注意点
pow() 関数は double 型を返すため、指数が大きくなると浮動小数点数の精度限界により誤差が生じる可能性があります。より大きな冪乗を正確に扱いたい場合は、unsigned long long 型による繰り返し乗算や、多倍長整数ライブラリの利用を検討するとよいでしょう。
また、このアルゴリズムの計算量は各冪乗値の桁数の総和に比例します。n が大きくなるほど桁数も急激に増加するため、実際に使用する際は扱う値の範囲に注意してください。
-
C++でM個の数字から作れる、5で割り切れるN桁の数の個数を求める方法
ある整数Nと、M個の数字からなる配列が与えられます。このとき、与えられたM個の数字を使って作成できるN桁の数のうち、5で割り切れるものの個数を求めるのが本記事のテーマです。まず、入力と出力の例を見ながら、問題の内容を確認していきましょう。入力 −N = 2 M = 3 arr = {5, 6, 3}出力 −2この場合、5で割り切れるN桁の数は「35」と「65」の2つです。続いて、別の例を見てみます。入力 −N = 1 M = 7 arr = {2, 3, 4, 5, 6, 7, 8}出力 −1配列の中で5で割り切れる1桁の数は「5」だけなので、答えは1となります。つまりこの問題は、「与えられた
-
C++で先行順走査(プレオーダー)から完全k分木を構築する方法
配列 arr[] には、k分木(k-ary tree)の先行順走査(プレオーダートラバーサル)の結果が順番に格納されています。この記事の目標は、その配列をもとに同じk分木を構築し、後行順走査(ポストオーダートラバーサル)の結果を出力することです。 ここでいう完全k分木(full k-ary tree)とは、各ノードが「0個」または「k個」の子ノードを持つ、すなわち最大でもk個の子しか持たない木のことです。 例 入力 int arr[] = {2, 5, 1, 3, 6, 7, 2, 1 }, int size = 8, int children = 2 出力 2つの子を持つ完全k分木を先行順