В основном, amritanshu имел довольно хорошую идею : у вас есть список основных факторов и вы разбили этот список на список, содержащий K самых больших факторов, и другой, содержащий другое простое числофакторы:
[2, 2], [3, 5, 7]
Затем вы умножаете самый большой элемент первого списка на самый маленький элемент второго списка и перезаписываете элемент второго списка с результатом.Удалить самый большой элемент из первого списка.Повторяйте эти шаги, пока ваш первый список не станет пустым:
[2, 2], [3, 5, 7]
[2], [6, 5, 7] // 5 is now the smallest element
[], [6, 10, 7]
, вот еще один пример:
N = 2310 = 2 * 3 * 5 * 7 * 11
K = 3
[2, 3], [5, 7, 11]
[2], [15, 7, 11]
[], [15, 14, 11]
однако, этот алгоритм все еще не идеален для некоторых случаев, таких как N = 2310
,K = 2
:
[2, 3, 5], [7, 11]
[2, 3], [35, 11]
[2], [35, 33]
[], [35, 66] // better: [], [42, 55]
Итак, я подумал, что вы на самом деле хотите разделить факторы так, чтобы факторы были как можно ближе к корню K-й буквы N. Итак, я придумаю этот алгоритм:
- вычислите R, наименьшее целое число, большее или равное K-му корню из N
- , вычислите gcd для R и N
- , если gcd равно R,добавьте R в список, вызовите ваш алгоритм рекурсивно с помощью
N / R, K-1
, добавьте результат в список и верните список - , если gcd не равен R, добавьте его в R и перейдите к шагу 2
Вот немного кода Python:
import math
def gcd(a, b):
while b:
a, b = b, a % b
return a
def root(N, K):
R = int(math.exp(math.log(N) / K))
if R ** K < N:
R += 1
return R
def find_factors(N, K):
if K == 1:
return [N]
R = root(N, K)
while True:
GCD = gcd(N, R)
if GCD == R:
return [R] + find_factors(N // R, K-1)
R += GCD
РЕДАКТИРОВАТЬ:
Я только что заметил, что этот алгоритм все еще дает неверныйрезультаты во многих случаях.Правильный путь - увеличение R
до деления N
:
def find_factors(N, K):
if K == 1:
return [N]
R = root(N, K)
while True:
if N % R == 0:
return [R] + find_factors(N // R, K-1)
R += 1
Таким образом, вам не нужно gcd
.