@lil_web

Как найти последную ненулевую цифру K!?

Задачка по программированию. Помогите решить.

Маша составляет последовательность, где на K месте стоит последняя ненулевая цифра K!. Помогите ей заполнить пропуски.

Входные данные:
Первая и единственная строка содержит число K (0 ≤ K ≤ 105)

Выходные данные:
Последная ненулевая цифра K!

Пример: ввели 5, вывелось 2.
  • Вопрос задан
  • 1038 просмотров
Решения вопроса 1
AnnTHony
@AnnTHony
Интроверт
ideone

<?php

function normalize($num)
{
	while ($num % 10 == 0)
	{
		$num = intdiv($num, 10);
	}
	
	return ($num % 100);
}

$k = 50; //  k! = 30414093201713378043612608166064768844377641568960512000000000000
$result = 1;

for ($i = 2; $i <= $k; $i++)
{
	$result = normalize($result * $i);
}

echo $result % 10; //  2
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
wataru
@wataru Куратор тега Алгоритмы
Разработчик на С++, экс-олимпиадник.
Можно быстро, за log (k) подсчитать, сколько там нулей в k!

Для этого какая там степерь 2 и 5 и возьмите минимум.
Простое p войдет в k! в степени floor(k/p) + floor(k/p^2) + floor(l/p^3)...
Можно легко это реализовать рекурсивно PowerInFactorial(n, p) = n >= p ? n/p + PowerInFactorial(n/p) : 0;

Теперь вы знаете, сколько нулей в факториале. Если их все убрать, то задача становится совсем простой - найти последнюю цифру. Это можно сделать просто ведя все вычисления по модулю 10.

Т.е. перемножаете все числа от 2 до k, предворительно сокращая двойки и пятерки, сколько надо.

twos = fives = min(PowerInFactorial(k, 2), PowerInFactorial(k, 5));
ans = 1;
for ( i = 2; i <= k; i++) {
  j = i;
  while (j % 2 == 0 && twos > 0) {
    j/=2;
    twos--;
  }
  // same for fives
  ...
  ...
  ans = (ans*j)%10;
}


В итоге решение за O(k), потому что вложенные циклы вполнятся суммарно столько раз, сколько нулей в k!, а их по формуле выше, меньше O(k).
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы