Для любого N позвольте f (N) быть последними пятью цифрами перед конечными нулями в N!. Например,
9! = 362880 so f(9)=36288 10! = 3628800 so f(10)=36288 20! = 2432902008176640000 so f(20)=17664
Найдите f (1,000,000,000,000)
Я успешно занялся этим вопросом для данных примеров, моя функция может правильно найти f (9), f (10), и т.д. Однако это борется с большим числом, особенно число, которое проблема просит - f (10^12).
Моя текущая оптимизация следующие: Я удаляю конечные нули из множителя и суммы, и сокращаю сумму к 5 цифрам после каждого умножения. Код в Python следующие:
def SFTR (n):
sum, a = 1, 2
while a < n+1:
mul = int(re.sub("0+$","",str(a)))
sum *= mul
sum = int(re.sub("0+$","",str(sum))[-5:])
a += 1
return sum
Может любой говорить мне, почему эта функция масштабируется так в основном, и почему ее занимание много времени. Кроме того, если кто-либо мог бы подсказать меня в корректном направлении для оптимизации моего алгоритма. (имя общей темы будет достаточно), Спасибо.
Обновление:
Я внес некоторые изменения для оптимизации, и это значительно быстрее, но это все еще не достаточно быстро для f (10^12). Кто-либо может сказать мне, что делает мой код медленным или как сделать его быстрее?
def SFTR (n):
sum, a = 1, 2
while a < n+1:
mul = a
while(mul % 10 == 0): mul = mul/10
mul = mul % 100000
sum *= mul
while(sum % 10 == 0): sum = sum/10
sum = sum % 100000
a += 1
return sum
mul
может стать очень большим. Это необходимо? Если бы я попросил вас вычислить последние 5 ненулевых цифр 1278348572934847283948561278387487189900038 * 38758
вручную , сколько именно цифр первого числа вам действительно нужно знать?
Фактически, вы могли бы даже заметить, что существует только ограниченный набор возможных конечных ненулевых цифр. Если я правильно помню, есть только несколько тысяч возможных конечных комбинаций ненулевых цифр, если вы посмотрите только на последние 5 цифр. Например, может ли последняя ненулевая цифра быть нечетной? (Здесь не обращайте внимания на особые случаи 0! И 1!)
Построение строк часто обходится дорого. Я бы предпочел использовать оператор по модулю при усечении до последних пяти цифр.
python -m timeit 'x = str(111111111111111111111111111111111)[-5:]'
1000000 loops, best of 3: 1.09 usec per loop
python -m timeit 'x = 111111111111111111111111111111111 % 100000'
1000000 loops, best of 3: 0.277 usec per loop
То же самое относится к удалению конечных нулей. Должен быть более эффективный способ сделать это, и вам, вероятно, не придется делать это на каждом этапе.
Я не проверял ваш алгоритм на правильность, это просто подсказка для оптимизации.