Pythonでn個の数値の積の末尾に連続するゼロの個数を求める方法
n個の数値からなる配列が与えられたとき、それらすべてを掛け合わせた結果の末尾に、ゼロがいくつ連続して並ぶかを求める問題について解説します。
例えば、入力が [200, 20, 5, 30, 40, 14] の場合を考えてみましょう。200 × 20 × 5 × 30 × 40 × 14 = 336000000 となり、末尾には6個のゼロが続くため、出力は 6 になります。
考え方:2と5の因数を数える
積の末尾にゼロが付くのは、「2」と「5」がペアになって掛け合わされ、10の倍数が生まれた場合です。したがって、各数値に含まれる2の因数の総数と5の因数の総数をそれぞれ数え、そのうち小さい方の値が末尾のゼロの個数となります。
具体的な手順は以下の通りです。
- 関数 count_fact_two() を定義します。引数として n を受け取ります
- count := 0 と初期化します
- n を 2 で割った余りが 0 の間、次を繰り返します
- count := count + 1
- n := n / 2(商のみ、整数除算)
- count を返します
- 同様に関数 count_fact_five() を定義します。2ではなく5で割り続ける点だけが異なります
- メイン処理では以下を実行します
- n := 配列 A のサイズ
- twos := 0、fives := 0 と初期化します
- i を 0 から n-1 まで繰り返します
- twos := twos + count_fact_two(A[i])
- fives := fives + count_fact_five(A[i])
- twos と fives のうち小さい方の値を返します(これが末尾のゼロの個数です)
なぜ小さい方を返すのか?
10 = 2 × 5 であるため、末尾のゼロ1個は「2と5のペア」1組に対応します。どちらか一方が不足するとペアを作れないため、2の因数と5の因数のうち少ない方の数が、作れる10の個数、すなわち末尾のゼロの個数になります。上記の例では、全体に含まれる5の因数が6個であるため、答えは6となります。
実装例
理解を深めるために、以下のPythonコードを見てみましょう。
def count_fact_two(n):
count = 0
while n % 2 == 0:
count += 1
n = n // 2
return count
def count_fact_five(n):
count = 0
while n % 5 == 0:
count += 1
n = n // 5
return count
def get_consecutive_zeros(A):
n = len(A)
twos = 0
fives = 0
for i in range(n):
twos += count_fact_two(A[i])
fives += count_fact_five(A[i])
if twos < fives:
return twos
else:
return fives
A = [200, 20, 5, 30, 40, 14]
print(get_consecutive_zeros(A))
入力
[200, 20, 5, 30, 40, 14]
出力
6
計算量について
このアルゴリズムは、各要素に対して2または5で割り切れなくなるまで除算を繰り返すため、時間計算量は配列の長さを n、最大値を M とすると O(n log M) 程度になります。実際に巨大な積を計算する必要がないため、数値が非常に大きくなる場合でも効率的に動作するのが大きな利点です。
-
Pythonでリスト内の最小値を見つける方法を解説
この記事では、リストの中から最小の数値を見つける方法について、具体的なサンプルコードとともに詳しく解説します。問題の概要問題: 数値のリストが与えられたとき、その中に含まれる最も小さい数値を画面に表示すること。この問題を解くアプローチは主に2つあります。ひとつは sort() メソッドを使ってリストを昇順に並べ替え、先頭の要素(インデックス0)を取得する方法。もうひとつは、Pythonに標準で用意されている組み込み関数 min() を使う方法です。それぞれ順番に見ていきましょう。方法1:sort()メソッドで並べ替えて最小値を取得するまずはリストを昇順にソートし、先頭の要素を取り出す方法です。
-
Pythonで数値の階乗を求める方法を解説!forループとrange関数の使い方
階乗(factorial)とは、1からその数までのすべての整数を掛け合わせた積のことです。例えば、5の階乗は「5 × 4 × 3 × 2 × 1 = 120」となります。 Pythonで指定した数の階乗を求めるには、range()関数を使って1からその数まで繰り返すforループを作成します。ここで注意すべき点は、range()関数は終了値(ストップ値)を含まないという仕様です。そのため、終了値は入力された数値より1大きい値(num+1)を指定する必要があります。 階乗を求めるPythonコードの例 ループ内では、各数値を変数 f に累積的に掛けていきます。この変数 f は初期値として 1 を設