C++で各数値から0をすべて削除した後にa+b=cが成立するかどうかを判定する方法
3つの整数 a、b、c が与えられたとき、それぞれの数値から「0」という桁をすべて取り除いた後も、等式 a + b = c が成り立つかどうかを判定する問題を考えてみましょう。
例として、a = 102、b = 130、c = 2005 の場合を見てみます。各数値から0を削除すると、それぞれ 12、13、25 になります。このとき 12 + 13 = 25 が成立するため、答えは「真(true)」となります。
解決のアプローチ
基本的な考え方はシンプルです。
- まず、各数値に含まれる0の桁をすべて削除した新しい数値を作成します。
- 次に、変換後の a と b を足し合わせた結果が、変換後の c と一致するかどうかを比較します。
- 一致すれば true、一致しなければ false を返します。
0の削除は、数値を下の桁から順に走査し、0以外の桁だけを新しい位置に詰めていくことで実現できます。
C++による実装例
#include <iostream>
#include <algorithm>
using namespace std;
// 数値から0の桁をすべて削除する関数
int deleteZeros(int n) {
int res = 0;
int place = 1;
while (n > 0) {
if (n % 10 != 0) { // 最下位の桁が0でない場合
res += (n % 10) * place;
place *= 10;
}
n /= 10;
}
return res;
}
// 0を削除した後に a + b = c が成り立つか判定する関数
bool isSame(int a, int b, int c) {
if (deleteZeros(a) + deleteZeros(b) == deleteZeros(c))
return true;
return false;
}
int main() {
int a = 102, b = 130, c = 2005;
if (isSame(a, b, c))
cout << "a + b = c は成立しています";
else
cout << "a + b = c は成立していません";
}
実行結果
a + b = c は成立しています
処理の流れの解説
deleteZeros 関数では、引数 n を10で割った余り(最下位の桁)を順番に調べます。その桁が0でなければ、現在の place(桁の重み)を掛けて結果に加算し、place を10倍して次の桁へ進めます。0の桁は単純にスキップされるため、結果として0を含まない数値が得られます。
isSame 関数は、3つの数値それぞれに deleteZeros を適用した上で、a + b == c が成立するかを比較しています。
このアルゴリズムの計算量は、各数値の桁数に比例するため、O(log₁₀N) と非常に効率的です。大きな数値でも高速に処理できる点が魅力です。
-
C++で二分探索木(BST)からCeiling(天井)とFloor(床)を求める方法
本記事では、二分探索木(BST)からCeiling(天井)値とFloor(床)値を求める方法について解説します。まず用語を整理しておきましょう。あるキーに対する「Ceiling」とは、そのキー以上の値の中で最小の要素を指し、「Floor」とはそのキー以下の値の中で最大の要素を指します。応用例:メモリ管理システム例えば、メモリ管理システムを構築することを考えてみます。空きメモリブロック(フリーノード)がBST上に配置されており、入力された要求サイズに対して最適なフィット(ベストフィット)を見つけたい場面です。このとき、ツリーを降下しながら「キー値より大きい最小のデータ」を追跡していくことになりま
-
C++で対角行列・スカラー行列を判定するプログラムの書き方
行列 M[r][c] が与えられたとき、「r」は行数、「c」は列数を表し、r = c のとき正方行列となります。本記事では、与えられた正方行列が対角行列であるか、スカラー行列であるかを判定し、該当する場合には「yes」を出力する方法を解説します。 対角行列とは 正方行列 m[][] が対角行列であるのは、主対角線以外の要素がすべてゼロである場合、かつその場合に限ります。 下図のように、赤色で示された要素が主対角成分(非ゼロ)であり、それ以外の要素はすべてゼロになっているため、この行列は対角行列です。 入出力例 Input: m[3][3] = { {7, 0, 0}, {0, 8, 0}