C++で与えられた方程式の解の個数を求める方法
この問題では、3つの整数 A、B、C が与えられます。私たちの課題は、与えられた方程式を満たす解の個数を求めることです。
対象となる方程式
X = B*Sm(X)^A + C
ここで、Sm(X) は X の各桁の数字を合計した値(桁和)を表します。
つまり、1 以上 109 以下の範囲に存在する整数の中から、上記の方程式を満たすすべての X の値を数える必要があります。
具体例を見て、問題を理解しましょう。
入力:
A = 3, B = 6, C = 4
出力:
3
解法のアプローチ
この問題を効率よく解く鍵となるのが「桁和」です。X の最大値は 999999999(9が9個)なので、桁和の最大値は 81(9 × 9桁)となります。さらに重要な点として、桁和の値が決まれば、方程式の右辺 B*Sm(X)A + C の値も一意に決まるという性質があります。
そこで、桁和の候補値を 1 から 81 まで順番に試します。各桁和の値から計算される解の候補について、実際にその数字の桁和が元の値と一致するか、そして値が 109 未満に収まっているかを確認すればよいのです。この方法なら、探索範囲はたった 81 通りしかなく、非常に高速に答えを求められます。
アルゴリズムの手順
- 桁和の候補 digSum を 1 から 81 まで繰り返し処理する。
- 各 digSum に対して、solVal = B × digSumA + C を計算する。
- solVal の各桁の合計を求め、digSum と一致し、かつ solVal が 109 未満であれば解としてカウントする。
- 最終的なカウントを出力する。
C++による実装例
上記の解法の動作を示すプログラムは以下の通りです。
#include <bits/stdc++.h>
using namespace std;
int countSolutions(int a, int b, int c){
int solutionCount = 0;
// 桁和の最大値は81(999999999の場合)
for (int digSum = 1; digSum <= 81; digSum++) {
int solVal = b * pow(digSum, a) + c;
int temp = solVal;
int sum = 0;
// solValの桁和を計算
while (temp) {
sum += temp % 10;
temp /= 10;
}
// 桁和が一致し、範囲内であれば解としてカウント
if (sum == digSum && solVal < 1e9)
solutionCount++;
}
return solutionCount;
}
int main(){
int a = 3, b = 6, c = 4;
cout<<"The number of solutions of the equations is "<<countSolutions(a, b, c);
return 0;
}
出力
The number of solutions of the equations is 3
計算量について
この解法では、桁和の候補は最大 81 通り、さらに各候補に対する桁和の計算は最大でも 10 回程度の除算・剰余演算で済むため、全体の計算量はほぼ定数時間 O(1) と見なせます。X の範囲である 109 通りを全探索する必要がないため、非常に効率的なアプローチだと言えます。
-
【C++】グラフ内の橋(ブリッジエッジ)の数を検出するプログラムの解説
ブリッジエッジ(橋)とは? 重みなし無向グラフにおけるブリッジエッジ(橋)とは、その辺を取り除いたときにグラフが非連結(複数の連結成分に分断される)となるような辺のことです。本記事では、n個の頂点とm個の辺からなるグラフが与えられたとき、その中に含まれるブリッジの数を求めるC++プログラムを紹介します。なお、対象となるグラフには平行辺や自己ループは含まれないものとします。 問題の例 例として、n = 5、m = 6、edges = {{1, 2}, {1, 3}, {2, 3}, {2, 4}, {2, 5}, {3, 5}} という入力が与えられた場合を考えてみましょう。この場合の出力は
-
C++で文字列の順列の総数を求めるプログラムの作成方法
文字列に含まれる文字は、さまざまな順序で並べ替えることができます。本記事では、与えられた文字列から作成できる順列の数を求める方法を解説します。たとえば「abc」という3文字の文字列の場合、並べ方は 3! = 6 通りあります。つまり、n 文字の文字列であれば、最大で n! 通りの並べ方が存在します。しかし、「aab」のように同じ文字が複数回含まれている場合、単純に 6 通りにはなりません。「aab」の全パターンを書き出してみると、次のようになります。abaaabbaabaaaababaこのうち、(1番目と6番目)、(2番目と5番目)、(3番目と4番目) のペアはそれぞれ同一の並び方です。したが