Найдите четыре делителя числа, произведение которых максимально, а сумма равна исходному числу.

Учитывая количество тестовых случаев T и целое число N, вам нужно найти четыре целых числа A,B,C,D , чтобы все они были факторами N(A|N,B|N,C|N,D|N ) и N=A+B+C+D. Цель состоит в том, чтобы максимизировать A * B * C * D. Если невозможно найти такие четыре фактора, просто верните -1.

Формат ввода для задачи:
Первая строка содержит целое число T(1 ‹=T‹=40000), представляет количество тестов.
Каждая из следующих T строк содержит целое число N (1‹=N‹=40000, N^4 не будет превышать 64-битного целого числа).

Этот вопрос находится на Hackerearth в категории рекурсии, но я не могу понять алгоритм в редакционной статье (редакционная ссылка: - https://www.hackerearth.com/practice/basic-programming/recursion/рекурсия-и-возврат/проблемы-практики/алгоритм/номер-разделения-a410603f/editorial/).

В редакционной статье это было решено с использованием единичных дробей, но я не могу понять алгоритм (я предоставил редакционную статью ниже, если вы не можете открыть приведенную выше ссылку, я не могу понять пункты, отмеченные ***). Решение грубой силы приводит к TLE (превышено ограничение по времени). Предоставьте алгоритм или псевдокод с использованием DFS или поиска с возвратом.

Мой подход грубой силы: вычислить коэффициенты числа 'n' в O (sqrt (n)) и сохранить их в массиве, а затем пройти по массиву, чтобы получить A, B, C, D, используя четыре цикла for. Но для тестов T(1‹=T‹=40000) он получает TLE.

От редакции(Если вы не можете открыть вышеуказанную ссылку):-

Рассмотрим уравнение N = A+B+C+D , если разделить уравнение на N , получим 1 = 1/A' + 1/B' + 1/C' + 1/D' , здесь A',B ',C',D' являются целыми числами, потому что A,B,C,D являются множителями числа N.

Таким образом, исходная задача равна делению 1 на четыре единицы измерения.

Мы можем перечислить единичные дроби от больших к малым.

*** Если нам нужно разделить X на Y единичных дробей, а последней единичной дробью является 1/Z, мы можем перечислить единичные дроби между 1/Z и X/Y (поскольку мы перечисляем наибольшую оставшуюся дробь) и рекурсивно решать.

*** Найдя все решения уравнения 1 = 1/A' + 1/B' + 1/C' + 1/D' (около 20 решений, если числа упорядочены), мы можем перечислить их в каждом наборе входных данных. Если A', B', C', D' являются факторами N, мы можем использовать это решение для обновления ответа.

Временная сложность: O(T), где T — количество тестовых случаев.


person dark_prince    schedule 30.03.2020    source источник


Ответы (2)


*** Если нам нужно разделить X на Y единичных дробей, а последней единичной дробью является 1/Z, мы можем перечислить единичные дроби между 1/Z и X/Y (поскольку мы перечисляем наибольшую оставшуюся дробь) и рекурсивно решать.

Ответ: Мы пытаемся найти все комбинации из 1 = 1/A + 1/B + 1/C + 1/D. Изначально у нас есть X=1 и Y=4, и мы перечисляем A как наибольший фактор, который должен быть не меньше, чем X/Y = 1/4. Поскольку это первый элемент, последней дроби 1/Z не существует. Предположим, мы выбрали A=3, поэтому последняя дробь 1/Z равна 1/A=1/3, X=1-1/3=2/3 и Y=3. Теперь выберем 1/B из [X/Y, 1/Z] = [2/9, 1/3]. И сделайте то же самое для следующих шагов.

*** Найдя все решения уравнения 1 = 1/A' + 1/B' + 1/C' + 1/D' (около 20 решений, если числа упорядочены), мы можем перечислить их в каждом наборе входных данных. Если A', B', C', D' являются факторами N, мы можем использовать это решение для обновления ответа.

Ответ: Поскольку 1/A должно быть не меньше 1/4, значит, A может быть только 2, 3, 4. Если A==4, то A=B=C=D имеет только одно решение. Если A == 3, [X/Y, 1/Z] = [2/9, 1/3], поэтому B может быть только 3 или 4, если B == 4, то следующий раунд C должен быть 4, где [ X/Y, 1/Z] = [5/24, 1/4]; если B=3, то C может быть 4,5,6, потому что [X/Y, 1/Z]=[1/6,1/3]. Если A==2, [X/Y, 1/Z] = [1/6, 1/2], B может быть 3,4,5,6. Вы можете сделать остальные вычисления, используя код, чувствуя, что мы можем отрезать много поисковых ветвей. (Не обращайте внимания на мой порядок перечисления, вы должны начать с A = 2.)

person Auggie Li    schedule 31.03.2020
comment
Спасибо, теперь я понял. Я также написал код, и он работает. - person dark_prince; 05.04.2020
comment
@dark_prince Уловка, используйте N/B вместо 1/B. Это облегчит ваши расчеты, чтобы избежать обыкновенной дроби, потому что N можно разделить на B. - person Auggie Li; 05.04.2020

Временную сложность вашего кода можно улучшить, используя только 3 цикла for и применяя двоичный поиск для нахождения четвертого числа, поскольку временная сложность двоичного поиска равна log(n). Временная сложность = O (n ^ 3 * (log (n)) и в соответствии с ограничениями вопроса он должен пройти все тестовые примеры.

person Karn3003    schedule 02.04.2020
comment
Я также использовал три цикла, и мне не нужно использовать двоичный поиск (четвертое число = N-A-B-C). На самом деле общее количество факторов приблизительно равно O(sqrt(3*n))(math.stackexchange.com/questions/1699330/), поэтому использование трех циклов означает O(nsqrt(n)) и для T тестовых случаев это будет O(Tnqrt(n)), что превысит ограничение по времени - person dark_prince; 05.04.2020
comment
Обратитесь к этому: текст ссылки - person Karn3003; 05.04.2020
comment
Существует небольшая разница между вопросом hackerearth и вопросом, упомянутым в приведенной выше ссылке, в вопросе для гиков нет тестовых примеров, которые вызывают TLE в hackerearth, но эффективный подход (последний) является лучшим решением ( временная сложность O ( log(n)), который дает временную сложность для T тестовых случаев (T*log(n)), спасибо за предоставление ссылки на gfg. - person dark_prince; 05.04.2020
comment
я не думаю, что нам нужно использовать двоичный поиск для четвертого числа, как указано в разделе о лучшем подходе (второй), потому что четвертое число = N-A-B-C, и нам нужно просто проверить, делит ли оно N или нет. - person dark_prince; 05.04.2020