Задать вопрос
Ответы пользователя по тегу Python
  • Почему рекурсия неверно отрабатывает?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Ваша программа ломается, если X=Y, например.
    Чтобы ее исправить, вместо веса edge и сравнения его со стоимостью товара, передавайте в функцию число от 1 до 3. Если число <=1, то можно брать x и передавать 1. Если <=2 - то можно брать y и передавать 2, и т.д.
    Ответ написан
    2 комментария
  • Можно ли единожды обойти все вершины связного неориентированного графа и вернуться в начальную вершину?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Судя по описанию, вам нужен Гамильтонов путь.

    Эта задача NP-полна - следовательно, простого и быстрого алгоритма человечеству не известно. Можно делать полный перебор с отсечениями и эвристиками. Какие-нибудь методы имитации отжига или генетические алгоритмы могут работать быстрее, но это не точно и нужно долго и мучительно ковыряться, что бы оно заработало.
    Ответ написан
    Комментировать
  • Python: Сколькими способами можно представить заданное натуральное число N в виде суммы после- довательных нечетных натуральных чисел?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Сумма последовательных нечетных чисел - разность двух квадратов:

    1 + 3 + 5 + 7 = 16 - 0
    7 + 9 = 25 - 9

    Таким образом - вопрос в том, сколько различных пар квадратов дают разность в заданное N.

    N = a^2 - b^2 = (a-b)(a+b)

    Или же сколько чисел a и b, т.ч. N раскладывается на множители (a+b) и (a-b).

    Достаточно найти все делители N (не больше корня) т.ч. делитель и оставшаяся часть имеют четную разность (эта разность же равна 2b). Т.е. (n/d - d) %2 = 0.

    Перебирайте все числа d до корня N, и если N%d == 0 and (N/d -d) %2 == 0, то прибавляйте единицу к ответу.
    Ответ написан
    Комментировать
  • Как проверить массив на возрастание?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Ваше решение не работает на примере 3,4,1,2. Тут нельзя удалить одно число, но ваша программа вернет true.

    В случае, если вы нашли один участок с убывающими соседними числами, надо проверить, что будет если удалить первое или второе число.
    Ответ написан
    Комментировать
  • Как оптимизировать простенький код?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Оптимизировать неправильное решение бесполезно. Тут 2 варианта:
    1) Реализовать бинарный поиск. У вас уже правильная идея, как определить, что за заданное количество секунд можно напечатать сколько надо или больше страниц (floor(seconds/s1)+floor(seconds/s2) >= n). Теперь осталось вместо линейного увеличения seconds, удваивать его. Т.е. вместо seconds = seconds+1 делать seconds = seconds*2. После чего сделать бинарный поиск на отрезке [1,seconds].

    2) Применить математику. Нужно найти минимальное x такое, что floor(x/s1)+floor(x/s2) >= n.

    Забъем на округление и решим x/s1 + x/s2 >= n.
    x = ceil(n*s1*s2/(s1+s2)).

    Но. это будет оценка сверху, потому что мы выкинули округления, которые уменьшают реальное значение количества напечатанных за x секунд страниц. Но, внимание, реальное количество страниц будет максимум на 2 страницы меньше, потому что oкругление сбивает максимум 1 страницу.

    Теперь будем увеличивать x, чтобы увеличить количество напечатанных страниц. Если просто прибавлять 1 каждый раз, то почти всегда занчение не поменяется, потому что x/s1 так и будет дробным. Увеличение произойдет только когда x/s1 или x/s2 будет целым. Следующее такое число можно легко найти (это будет x, делящееся на s1 или s2. Итак, решение:

    def twoprinters(s1,s2,pages):
        seconds= int(pages*s1*s2 + s1 + s2 - 1)/(s1+s2)
        while int(seconds/s1)+int(seconds/s2) < pages:
                a = seconds - seconds%s1 + s1
                b = seconds - seconds%s2 + s2
                seconds = min(a,b)


    Этот код будет работать мгновенно для очень больших чисел. Потому что цикл while тут будет исполнятся максимум 2 раза. Каждый раз значение напечатанных страниц будет увеличиваться как минимум на 1, а оно изначально будет максимум на 2 меньше ответа. Странные вычисления a и b - это следующие числа за seconds, которые делятся на s1 и s2 соответственно. Мы вычитаем остаток от деления и получаем предыдущее или равное seconds число, делящееся на s1 и s2. Прибавляя s1 или s2 мы получаем следующее число, как нам и надо.
    Ответ написан
    Комментировать
  • Есть ли способ автоматически вывести сложность алгоритма (Python)?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Нет нельзя. Потому что нельзя даже определить, завершается ли программа, или виснет. Это называется проблема остановки (https://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%BE%D... Логически доказано, что невозможно автоматически решить ее.

    Подобным образом можно доказать, что не существует программы, определяющей сложность любой программы.
    Допустим, что такая программа есть. Напишем другую программу, которая анализирует входной исходный код этой первой программой (пусть она получила оценку f(N)), а потом делает что-то неважное (например прибавляет 1 к переменной) f(N)*N раз. Теперь запустим эту программу на собственном исходном коде. Она получит оценку своей сложности и потом сделает что-то в N раз больше. Т.е. фактически сделано f(N)*N операций, но программа же оценила этот код как O(f(N)) на этих входных данных, что неверно.

    Можно написать что-то тупое и наивное, вроде подсчета количества вложенных циклов, но работать будет только в очень частных случаях и часто ошибаться.
    Ответ написан
    Комментировать