Задать вопрос
Ответы пользователя по тегу Алгоритмы
  • Фибоначчи без использования BigInt на javascript?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Без BigInt - никак. Числа-то большие получаются. Если нет библиотеки, придется самостоятельно писать длинную арифметику. Просто храните цифры числа в массиве и длину рядом. Вам надо будет только сложение реализовывать, ну это делается столбиком одним циклом. Храните перенос с младших разрядов в переменной. Можно или исходники BigInt поискать, или вот тут посмотреть
    Ответ написан
    Комментировать
  • Проблема с оптимизацией сортировки методом Bubble sort. Как ускорить сортировку для списка из 100 тысяч элементов?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Никак не ускорить. Сортировка пузырьком - медленная. Имеет квадратичное время выполнения. для 100000 элементов там будет 5 миллиардов сравнений в худшем случае. Для случайных массивов в пару раз меньше в среднем. С учетом, что это питон - вам этих 2х миллиардов операций придется ждать минуту. А с учетом 10 повторений - все 10 минут.
    Ответ написан
    3 комментария
  • Как решать задачу используя динамическое программирование?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Какой-то идиот задачу составлял.
    Во-первых, для N<60 ответ помещается в 64-битный целочисленный тип, который есть сейчас практически во всех языках программирования. Тут не надо ничего придумывать для избегания переполнения.
    Во-вторых, чтобы избежать переполнения, в таких задачах обычно просят выдать ответ по какому-то большому модулю. И последнее, как ответ может получиться нецелым - это просто загадка. Пример решения явно неверен.

    А так, динамическое программирование тут простое: Пусть F(N,K) - сколько существует невзрывоопасных стопок длины N, таких что в конце есть ровно K опасных контейнеров (очевидно, 0 <= K < 4). Это не совсем прям то, что вам нужно в задаче, но количество опасных стопок - это количество всех стопок (2^N) минус количество невзрывоопасных, поэтому это ДП нам подходит.

    Пересчет очень прост:

    F(N,K>0) = F(N-K,0)
    F(N,0) = F(N-1,0)+F(N-1,1)+F(N-1,2)+F(N-1,3)


    Если на конце K плохих контейнеров, то до этого точно должен быть хороший контейнер. Если на конце стоит хороший контейнер - то до него может быть 0..3 плохих контейнера.

    База: F(0,0) = 1, F(0, K>0) = 0

    Ответ: 2^N - F(N,0)-F(N,1)-F(N,2)-F(N,3)
    Ответ написан
    2 комментария
  • Почему моё решение данной задачи неправильное?

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

    У 28 шесть делителей (1, 2, 4, 7, 14, 28). Среди них есть делители 1 и 2, которые отличаются меньше чем на d=3.
    Ответ написан
    1 комментарий
  • Как решить задачу про кузнечика путем динамического программирования?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Опишите ваше динамическое программирование - физический смысл функции и рекуррентное соотношение.
    Ответ написан
  • Как среди элементов списка найти такой, чётность которого уникальна?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Нельзя суммой проверять. Ведь если чисел в массиве четно, то сумма всегда будет нечетно (буть четным одно или n-1 в массиве).

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

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

    Есть куча статей и конференций на тему. Это активная область исследования и каких-то окончательных ответов тут человечество пока не придумало, но есть куча очень умных алгоримов.
    Ответ написан
    Комментировать
  • Как найти точки пересечения 2х фигур с++?

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

    upd: На этом же сайте есть все что нужно для проверки пересечения окружности и отрезков.
    Ответ написан
    2 комментария
  • Как найти наибольшее значение у такой функции?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Если ваша функция унимодальная (сначала возрастающая, потом убывающая), то можно применить троичный поиск.

    Правда, там трубуется, чтобы функция сторго возрастала а потом строго убывала.
    Если у вас функция горизонтальная на отрезках длины 1 (т.е. от целочисленных аргументов), то троичный поиск еще можно применить.

    Но если функция может принимать одинаковые значения на произвольном промежутке, то никаких логарифмических алгоритмов поиска максимума тут нет. Если обе промежуточные точки выдадут одно и то же значение, то никак не определить, в каком из трех промежутков лежит максимум.
    Ответ написан
    6 комментариев
  • Почему не проходит решение?

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

    Но ваша логика решения мне не понятна. Вам следует в каждой вершине поддерживать счётчик соседей листьев и их список. Далее, имейте очередь вершин с более чем k листьев рядом. Удаляйте k листьев. Если текущая стала листом (нужны счётчики для степени вершин), то добавьте её в список к единственному соседу.

    Чтобы не возиться с удалением соседей, помещайте вершины удаленными и при обходе списка соседей удаляйте их
    Ответ написан
  • Как реализовать дерево на основе связного списка?

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

    Возможно, вам надо хранить детей каждой вершины в виде связного списка (тогда у вас будет куча списков). Еще, популярный подход (фактически делающий то же самое) - это хранить в каждой вершине ссылку/указатель на первого ребенка и на следующего брата. Так все списки будут перемешаны в одну большую структуру. Но тут, правда, в отличии от связного списка, все равно есть 2 типа ссылок.
    Ответ написан
    2 комментария
  • Из какой коллекции можно быстро удалять элемент, но к ней применим бин. поиск?

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

    Там можно искать нужный вам элемент через floor или ceiling. Поиск и удаление, если создатели библиотеки в java хоть что-то слышали про алгоритмы и структуры данных, работают за логарифм.
    Ответ написан
    Комментировать
  • Чему будет равна сложность этого алгоритма?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Зависит от размеров item. Если они там каждый O(N) размера, то ваша догадка правильная: O(n^2 log n).

    Если же все item суммарно не превосходят N, то ответ O(N log N). Потому что если их размеры a_i, то у вас сумма ai log ai. log(ai) можно сверху ограничить log(N) и вынести за скобки и потом заменить сумму в скобках на N.
    Ответ написан
    1 комментарий
  • Как найти максимально похожий цвет?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Если скорость не особо важна, то просто пройдитесь по всем именным цветам (лучше, чтобы это был какой-то списко или массив, а не мап) и считайте какую-то метрику (например, сумма квадратов разности по каждому каналу отдельно). Из полученных чисел ищите минимум и выдавайте тот цвет, что ее дал.

    Если надо работать очень быстро, то надо представить ваши именные цвета как точки в трехмерном пространстве, построить kd-дерево или r-дерево и уже в нем искать ближайшую к запрошенной точку.
    Ответ написан
    5 комментариев
  • В чем моя ошибка в задаче?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    У вас правильная идея, что двух чисел в ответе всегда достаточно. Всегда можно выдать, например, n, n-1 и эти две операции покроют все позиции с 1 по n.

    Но вот случай, когда достаточно одного числа вы неправильно разобрали. Почему вы ищите самое большое простое число? Какой вообще смысл смотреть, что в позиции ans-1 стоит c?

    А еще ваш код выводит 0 неверно иногда.

    Вы, может, задачу неправильно поняли? Надо сделать так, что бы все позиции, в которых символы отличные от c, не делились бы на хотя бы одно число в вашем ответе.
    Ответ написан
    1 комментарий
  • Почему LCS алгоритм находит совпадение в конце последовательности?

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

    Построение матрицы менять не надо, оно просто считает оптимальную длину LCS. Вам надо отдавать приоритет переходам вверх (или влево) пока это возможно при восстановлении ответа.

    Но можно сделать простой хак - усеките ваш текст как можно короче, пока LCS все еще оптимального размера.

    Вам надо найти самое первое максимальное число в последней строке (или столбце, в зависимости от того в какой из входных строчек вы хотите как можно левее найти вхождение. Я не в курсе, что у вас за aCompareFunc).

    От этой позиции и запускайте ваш DoDiff вместо левой нижней ячейки матрицы.

    Значения максимума даже не надо искать, он будет в левом нижнем углу матрицы. Вам остается только циклом найти самое левое число в строке (столбце) равное последнему.

    Вам еще придется в конце зарепортить необходимое количество l3diffDeleted или l3diffAdded, чтобы восстановить усеченную часть.
    Ответ написан
    1 комментарий
  • Как в двоичном дереве поиска найти минимальный элемент, больший данного?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Надо, как в бинарном поиске - идти или в левое или в правое поддерево. Если пошли в левое поддерево, то надо проверить, что вернула рекурсивная функция - если там не было больших элементов, то надо вернуть значение в текущей вершине.
    Ответ написан
    3 комментария
  • Почему не получается найти подпоследовательность?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    У вас решение за O(MN), когда как можно за O(M log N).

    Вы говорите, что оно линейно, но вы выполняете линейное количество операций на каждый элемент массива b. Это медленно. Ваша проблема в том, что вы храните все индексы для каждого значения просто в списке и потом там наивно ищите первое вхождение больше данной границы. Можно список хранить в Set. Вот я не в курсе, умеет ли он, как C++-шный set искать первый элемент больше заданной границы. Если нет, то можно тупо хранить отсортированые списки индексов, тогда там можно будет делать бинпоиск.
    Ответ написан
    7 комментариев
  • Как сделать перебор всех значений строки определенной длины состоящей из цифр и букв?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Ну вот как вы прибавляете 1 к числу из 0..9 прибавляйте 1 к числу, где цифры могут быть 0..9 и a..z. Все z в конце замените на 0, следующий символ увеличте на 1 (если стало '9'+1, то Замените на 'a').
    Ответ написан
    Комментировать
  • Почему решение задачи неправильное?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    is_subsequence написана с ошибкой. Что у вас там за алгоритм? Почему вы считатете, что оно должно работать?

    Оно, например, не работает на тесте s="abc" t="zzzzzcba". Ваша реализация скажет, что abc является подпоследовательностью, хотя на самом деле - нет.

    Еще хочется отдельно привлечь внимание к гениальности кода:
    if (is_sub)
            return true;
        else
            return false;


    Он кажется мне немного перемудренным.
    Ответ написан
    1 комментарий