Легко.
В псевдокоде
a = b = floor(sqrt(N))
if (a * b >= N) return (a, b)
a += 1
if (a * b >= N) return (a, b)
return (a, b+1)
и оно всегда будет заканчиваться, расстояние между a
и b
не более 1. 1. 1008 *
Этобудет намного сложнее, если вы ослабите второе ограничение, но это другой вопрос.
Редактировать: так как кажется, что первое условие более важно, вы должны атаковать проблему немного по-другому.Вы должны указать какой-либо метод для измерения плохости недостаточности квадрата = 2-го условия, потому что даже простые числа могут быть разложены как 1*number
, и мы выполняем первое условие.Предположим, у нас есть функция плохости (скажем, a >= b && a <= 2 * b
), затем разложим на множители N
и попробуйте разные комбинации, чтобы найти лучшую.Если нет достаточно хороших, попробуйте с N+1
и т. Д.
Edit2: подумав немного, я пришел с этим решением, в Python:
from math import sqrt
def isok(a, b):
"""accept difference of five - 2nd rule"""
return a <= b + 5
def improve(a, b, N):
"""improve result:
if a == b:
(a+1)*(b-1) = a^2 - 1 < a*a
otherwise (a - 1 >= b as a is always larger)
(a+1)*(b-1) = a*b - a + b - 1 =< a*b
On each iteration new a*b will be less,
continue until we can, or 2nd condition is still met
"""
while (a+1) * (b-1) >= N and isok(a+1, b-1):
a, b = a + 1, b - 1
return (a, b)
def decomposite(N):
a = int(sqrt(N))
b = a
# N is square, result is ok
if a * b >= N:
return (a, b)
a += 1
if a * b >= N:
return improve(a, b, N)
return improve(a, b+1, N)
def test(N):
(a, b) = decomposite(N)
print "%d decomposed as %d * %d = %d" % (N, a, b, a*b)
[test(x) for x in [99, 100, 101, 20, 21, 22, 23]]
, которыйвыходы
99 decomposed as 11 * 9 = 99
100 decomposed as 10 * 10 = 100
101 decomposed as 13 * 8 = 104
20 decomposed as 5 * 4 = 20
21 decomposed as 7 * 3 = 21
22 decomposed as 6 * 4 = 24
23 decomposed as 6 * 4 = 24