Лучший алгоритм для нахождения максимального числа, на которое квадрат делит K :

Имея число K, являющееся произведением двух разных чисел (A,B), найдите максимальное число (‹=A & ‹=B), квадрат которого делит K. .

Например: К = 54 (6*9). Доступны оба числа, то есть 6 и 9.

Мой подход довольно прост или тривиален.

  1. берем наименьшее из двух (в данном случае 6). Допустим, A
  2. Возведите число в квадрат и разделите K, если это идеальное деление, то это число.
  3. В противном случае A = A-1, пока A = 1.

Для данного примера 3 * 3 = 9 делит K, и, следовательно, ответ 3.

Ищем лучший алгоритм, чем тривиальное решение.

Примечание. Тестовые случаи исчисляются тысячами, поэтому необходим наилучший подход.


person Sushim Mukul Dutta    schedule 20.12.2014    source источник
comment
k = 3 или как? вы можете использовать оператор for, который выполняет и завершает функцию и проверяет, является ли результат десятичным или нет.   -  person Irrational Person    schedule 20.12.2014
comment
@Bot K = 54, который является произведением A = 6 и B = 9, проблема ищет только положительные целые числа. Я уже запускаю цикл for, а точнее:   -  person Sushim Mukul Dutta    schedule 20.12.2014
comment
как правило, найти множители чисел непросто, я бы попробовал каждое квадратное число от 4 до sqrt (k), что должно быть довольно быстро.   -  person Mauricio Trajano    schedule 20.12.2014
comment
поэтому вы можете проверить 6 ^ 2 и 9 ^ 2, разделенные на 54. Затем найдите максимальное число, которое можно разделить на 54, чтобы получить целое число.   -  person Irrational Person    schedule 20.12.2014
comment
что будет делать ваш алгоритм, если заданные числа 1 * 54?   -  person Gouda    schedule 20.12.2014
comment
@MauricioTrajano Поскольку мы должны найти максимальное число, квадрат которого делит K, я взял его из меньшего из двух множителей (данный квадрат любого числа выше меньшего множителя (A) не может делить K), а затем перешел к , должен' t что меньше раз (петли), мы заставляем? Тем не менее, я думаю, что итерация в значительной степени приведет к тому же результату, поскольку SQRT 54 больше, чем 6. (7+)   -  person Sushim Mukul Dutta    schedule 20.12.2014
comment
@mGouda довольно просто, 1 * 54 = 54, 1 ^ 2 идеально делит число, поэтому 1 - это ответ.   -  person Sushim Mukul Dutta    schedule 20.12.2014
comment
@SushimMukulDutta, неправильно .. в случае 54 это может быть случайным ответом. но предположим, что K=100, мы знаем, что ответ равен 10 (максимальное число, квадрат которого делит K). Таким образом, если ввод был 100 = 1 * 100, приведенный выше алгоритм выведет 1, что не является максимально возможным выходом. На самом деле, я запутался в необходимости двух значений A и B.   -  person Gouda    schedule 20.12.2014
comment
@mGouda A=B также возможен, поэтому ответ может быть 10 при A=1 и B =100.   -  person Sushim Mukul Dutta    schedule 20.12.2014
comment
поэтому после редактирования вывод должен быть ‹=A и ‹=B. в моем примере 10 неприемлемо, так как не удовлетворяет этому условию, где A=1, B=100. Итак, 10 ‹= B верно. в то время как 10 ‹= A ложно   -  person Gouda    schedule 20.12.2014
comment
Да, правильно, однако, учитывая А = 10 и В = 10, ответ должен быть 10. Это был мой первый пункт, который я уже добавил в программу.   -  person Sushim Mukul Dutta    schedule 20.12.2014


Ответы (3)


Я уверен, что кто-то еще придумает хороший ответ, связанный с арифметикой модуля. Вот наивный подход...

Каждый из факторов может быть сам по себе факторизован (хотя это может быть дорогостоящей операцией).

Учитывая факторы, вы можете искать группы повторяющихся факторов.

Например, используя ваш пример:

Простые множители 9: 3, 3

Простые множители 6: 2, 3

Все простые множители: 2, 3, 3, 3

Есть две тройки, поэтому у вас есть ответ (квадрат 3 делит 54).

Второй пример 36 х 9 = 324

Простые множители числа 36: 2, 2, 3, 3

Простые множители 9: 3, 3

Все простые множители: 2, 2, 3, 3, 3, 3

Итак, у вас есть две двойки и четыре тройки, что означает повторение 2x3x3. 2x3x3 = 18, значит, квадрат 18 делит 324.

Изменить: прототип Python

import math

def factors(num, dict):
    """ This finds the factors of a number recursively.
        It is not the most efficient algorithm, and I 
        have not tested it a lot.  You should probably
        use another one. dict is a dictionary which looks
        like {factor: occurrences, factor: occurrences, ...}
        It must contain at least {2: 0} but need not have 
        any other pre-populated elements.  Factors will be added
        to this dictionary as they are found.
    """

    while (num % 2 == 0):
        num /= 2
        dict[2] += 1
    i = 3
    found = False
    while (not found and (i <= int(math.sqrt(num)))):
        if (num % i == 0):
            found = True
            factors(i, dict)
            factors(num / i, dict)
        else:
            i += 2
    if (not found):
        if (num in dict.keys()):
            dict[num] += 1
        else:
            dict[num] = 1
    return 0


#MAIN ROUTINE IS HERE

n1 = 37 # first number (6 in your example)
n2 = 41 # second number (9 in your example)
dict = {2: 0} # initialise factors (start with "no factors of 2")
factors(n1, dict) # find the factors of f1 and add them to the list
factors(n2, dict) # find the factors of f2 and add them to the list
sqfac = 1
# now find all factors repeated twice and multiply them together
for k in dict.keys():
    dict[k] /= 2
    sqfac *= k ** dict[k]
# here is the result
print(sqfac)
person Tony    schedule 20.12.2014
comment
хорошая идея, но помимо стоимости. Хотя это гарантирует, что выход делит K, но как он гарантирует, что это максимально возможный результат? - person Gouda; 20.12.2014
comment
@ Тони, отличная идея, однако стоимость поиска простых множителей факторов, а затем нахождения пересечения двух наборов - это то, к чему я немного скептически отношусь. Попробуй, сообщишь, спасибо :) - person Sushim Mukul Dutta; 20.12.2014
comment
@SushimMukulDutta, я добавил грубую реализацию Python. В настоящее время я не могу найти способ избежать поиска всех факторов и последующего поиска пар. Поиск пар после того, как вы рассчитали факторинг, стоит недорого. Факторинг может быть дорогим, но если вам нужно найти факторы, вы должны их найти! Есть более разумные способы факторинга, чем моя функция factors. - person Tony; 20.12.2014
comment
@mGouda, любое число N, квадрат которого делит K, должно быть произведением некоторого подмножества S простых множителей K. Кроме того, если N ^ 2 должно делить K, подмножество S должно появляться ровно дважды в простых множителях K. Просто найдите все простые множители, которые встречаются ровно дважды (повторения разрешены, поэтому 2, 2, 2, 2 — это 2, встречающиеся ровно дважды, и 2, встречающиеся ровно дважды), и все готово. - person Tony; 20.12.2014

Ответ на C++

int func(int i, j)
{ 
    int k = 54
    float result = pow(i, 2)/k
    if (static_cast<int>(result)) == result) 
    {
        if(i < j)
        {
            func(j, i);
        }
        else
        {
            cout << "Number is correct: " << i << endl;
        }
    }
    else
    {
        cout << "Number is wrong" << endl;
        func(j, i)

    }
 }

Пояснение:

Сначала рекурсия, затем проверьте, является ли результат положительным целым числом, если это так, то проверьте, меньше или больше другое кратное, если большая рекурсивная функция пробует другое кратное, и если нет, то это правильно. Затем, если результат не является положительным целым числом, выведите число неправильно и выполните другую рекурсивную функцию для проверки j.

person Irrational Person    schedule 20.12.2014
comment
Я немного не уверен, правильно ли вы поняли вопрос. Вот еще один пример. Давайте попробуем визуальный подход, учитывая прямоугольник L = 6 и B = 9, разделим прямоугольник на идеальные квадраты, не оставив площади. Задача состоит в том, чтобы найти максимальное значение стороны квадратов, которые будут разрезаны. - person Sushim Mukul Dutta; 20.12.2014
comment
поэтому (6 -> 9)/54 является максимальным значением - person Irrational Person; 20.12.2014

Если я правильно понял проблему, я вижу, что у вас есть прямоугольник длины = A, ширины = B и площади = K, и вы хотите преобразовать его в квадрат и потерять минимально возможную площадь.

Если это так. Таким образом, проблема с вашим алгоритмом заключается не в стоимости повторения нескольких итераций до получения результата. Скорее проблема в том, что ваш алгоритм сильно зависит от длины A и ширины B входного прямоугольника. В то время как она должна зависеть только от площади K

Например:

  • Предположим, что А = 1, В = 25.
  • Тогда K=25 (прямоугольная область)
  • Ваш алгоритм возьмет минимальное значение, равное A, и примет его как ответ с одной итерацией, которая настолько быстра, но приводит к неправильному ответу, поскольку в результате получается квадрат площади 1 и тратятся оставшиеся 24 (независимо от того, см или м)
  • В то время как правильный ответ здесь должен быть 5. который никогда не будет достигнут вашим алгоритмом

Итак, в моем решении я предполагаю один вход K

Мои идеи заключаются в следующем

  • х = квадрат (К)
  • if(x is int) .. x это ответ
  • иначе цикл от x-1 до 1, x--
  • если K/x^2 равно int, x является ответом

Это может потребовать дополнительных итераций, но гарантирует точный ответ. Кроме того, могут быть некоторые опасения по поводу стоимости sqrt (K), но он будет вызываться только один раз, чтобы избежать вводящих в заблуждение значений длины и ширины.

person Gouda    schedule 20.12.2014