C/C++プログラミング:階乗の末尾に連続するゼロの個数を数える方法
階乗の値の末尾に連続するゼロ(後続ゼロ)の個数を求めるには、その数の因数に含まれる「2」と「5」の個数を数えます。これは、2×5=10という組み合わせが、階乗の末尾にゼロを1つ生み出すためです。
例:7の階乗の場合
7の階乗(7!)は5040であり、末尾のゼロは1個です。
ロジックに基づいて確認してみましょう。7! = 2×3×4×5×6×7 であり、因数のうち2は3個、5は1個含まれています。ペアにできる2と5の組み合わせは1組だけなので、末尾のゼロの個数は1個となります。
効率的なアルゴリズム:5の個数だけを数える
階乗の因数において、2の個数は必ず5の個数以上になります。そのため、実際には5の個数だけを数えれば末尾のゼロの個数が求まります。
以下のプログラムでは、nを5で順に割っていくことで、5の倍数・25の倍数・125の倍数…に含まれる5の個数を効率的に合計しています。
#include <iostream>
using namespace std;
int main() {
int n = 45;
int count = 0;
for (int i = 5; n / i >= 1; i *= 5)
count += n / i;
cout<<"No of trailing 0s in " << n<< "! is " << count;
return 0;
}
出力結果
No of trailing 0s in 45! is 10
計算の流れを確認
n = 45の場合、プログラムは次のように動作します。
- 45 ÷ 5 = 9 → 5の倍数が9個(5, 10, 15, 20, 25, 30, 35, 40, 45)
- 45 ÷ 25 = 1 → 25の倍数が1個(25は5を2つ含むため、さらに1加算)
- 45 ÷ 125 = 0 → ループ終了
合計 9 + 1 = 10 となり、45! の末尾のゼロは10個であることがわかります。このアルゴリズムの計算量はO(log n)と非常に効率的で、大きな数の階乗でも高速に末尾ゼロの個数を求められます。
-
C++で解く!Nの階乗の16進数表現における末尾のゼロの個数の求め方
この記事では、与えられた整数Nの階乗(N!)を16進数で表したとき、末尾に何個のゼロが連続するかを求める問題について詳しく解説します。 入力 : N = 7 出力 : 1 説明 : fact(7) = 5040(10進数)で、16進数では13B0となり、末尾のゼロは1個です。 入力 : N = 11 出力 : 2 説明 : fact(11) = 39916800(10進数)で、16進数では2611500となり、末尾のゼロは2個です。 10進数から16進数への変換のおさらい まず、任意の10進数を別の基数へ変換する手順をおさらいしましょう。ここでは、(5040)10 を16進数に変換する例を
-
【C++】長方形に含まれる正方形の総数を求めるアルゴリズムと実装
縦の長さL、横の幅B(L≥B)の長方形が与えられたとします。この記事では、L×Bの長方形の中にいくつの正方形が含まれているかを効率的に求める方法を解説します。 上の図は3×2の長方形の例です。この長方形には、2×2の正方形が2個、1×1の正方形が6個含まれています。 合計:6+2=8個 規則性を見つける まず、正方形だけで構成されたB×Bの図形について考えてみましょう。 サイズL×Bの長方形には、必ずL×B個の1×1の正方形が含まれます。 含まれる最大の正方形のサイズはB×Bです。 L=B=1の場合:正方形の数=1 L=B=2の場合:正方形の数=1+4=5(2×2が1個、1×1が4個) L