• Дейкстра почти за линейное время (для неориентированного графа)?

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

    А так, да, на очень специфичных гарфах всеядный алгоритм Дейкстры не самый лучший вариант. И ваш алгоритм тут получается быстрее.

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

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Выглядит случайно. Так что надо или постигнуть запретную черную магию, чтобы видеть будущее, или изобрести машину времени.
    Ответ написан
    Комментировать
  • Почему один и тот же код даёт разные результаты компиляции?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Что этот код должен, по вашему делать? Я отлично вижу, как он может в этих случаях вернуть false. Если ваш цикл в вашем UNORDERED мапе сначала возьмет самый последний символ сторки part1, то он присвоит переменной order максимально возможное значение и больше ни одино условие в цикле не выполнется - ни один символ больше не удалится.

    Разница в поведении компиляторов обусловлена тем, что они по разному мешают этот самый НЕУПОРЯДОЧЕННЫЙ мап. Возможно, там разные хеш функции используются.

    И, кстати, ваши multimap-ы тут вообще бесполезны. Во-первых, зачем вам MULTImap, ведь у вас все ключи - это индексы симовлов - уже разные. Во-вторых, зачем вам вообще map, если вы там по каждому индексу храние символ, что итак уже делает строка! У вас там part1map[i] == part1[i] всегда. Вместо цикла по мапу, можно пройтись циклом от 0 до длины строки.
    Ответ написан
    Комментировать
  • Как набрать нужную сумму из определенного количества монет?

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

    Еще можно чуть по-другому: находите переблром все варианты одного размена. Потом у вас переменные будут, сколько раз каждый из вариантов берете. Ограничения на общий расход каждой монеты, а целевая функция - сумма переменных. Тут нет бинплиска, но тоже ЦЛП.
    Ответ написан
    Комментировать
  • Почему тут требуется cast double -> int?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вообще, преобразование из double в int - это не ошибка. Это warning (и то, он выводится, только если компилятору указать -Wconversion. Код выше этот варнинг выдает во втором месте, но все-равно компилируется.

    Если у вас преобразование умышленное, и вы знаете, что там не будет ошибки переоплнения, то вы можете использовать static_cast тогда компилятор не будет выдавать предупреждение.
    Ответ написан
  • Доработка алгоритмической задачи JAVA. Требуется помощь >?

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

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

    Поэтому решение будет из двух указателей - левого и правого. Пока они не сошлись, считайте площадь, сравнивайте ее с текущим ответом, а потом двигайте указатель на меньшее число в сторону второго.
    Ответ написан
    8 комментариев
  • Как вывести кратчайший путь в графе?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Вам надо в вашем алгоритме еще завести словарь, куда вы для каждой вершины будете складывать предыдущую в пути. Там, где вы соседнюю вершину кладете в очередь - там надо сарзу смотреть, посещенная она или нет и класть только если нет. Вот в этот момент вы знаете, что вы пришли в graph[city][i] из city.

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

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

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Правильный ответ 8!. Ваше второе рассуждение упускает то, что вы одну и ту же позицию получите 8! раз. Ибо вы там считаете все фигуры уникальными. Допустим это все ладьи по диагонали. Вы первую можете поставить в 8 мест - одно из 64. Вторую в 7, когда выбираете из 49... И т.д. Вот и получится, что одну позицию - все на диагонали - вы подсчитали 8! раз.
    Ответ написан
    6 комментариев
  • Где Decimal в C++?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Ну нет его в стандартной библиотеке, как и длинных чисел. Используйте gmplib, например.
    Ответ написан
    7 комментариев
  • Алгоритмы и структуры данных. Сложность алгоритмов?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Потому что это 2 разных графика, 2 разных примера. Могли бы на втором обозвать вместо f и g f` и g`. Но авторам, наверно, было лень.
    Ответ написан
    1 комментарий
  • Как проходить список и одновременно удалять элементы, в том числе впереди курсора?

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

    Еще можноиспользовать обычный list, только вы итерируйтесь циклом while и используйте индексы:
    i = 0
    while i < len(arr):
      x = arr[i]
      j = i+1
      while j < len(arr):
        if ShouldDelete(arr[j], arr[i]):
          del a[j]


    Это будет в n раз медленнее, к сожалению. Можно наверно слайсами сделать быстрее:

    arr[i+1:] = y for y in arr[i+1:] if not ShouldDelete(x, arr[i])


    Я не питонист и возможно ошибку допустил. И мне этот код не кажктся очень понятным, но возможно это истиный путь для питона.

    А так, в общем случае, идет двойная итерация с пометками элементов на удаление.

    Какого-то названия этот прием не имеет, ибо это костыль для конкретных реализаций контейнеров.
    Ответ написан
    Комментировать
  • Если использовать вместо UE5 OpenGL или SDL2 и C++ для создания 2D и 3D игры будет ли она работать эффективнее и занимать меньше места?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Теоретически - да. Специализированный движок лишь для вашей игры будет быстрее и легче многофункционального комбайна UE. На практике у вас там объем работы будет на сотню человеко-лет.
    Ответ написан
    1 комментарий
  • Баг цикла или как это объяснить?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Подсказка: вот то число, что у вас в конце выводится - это 2^64-1. Еще подсказка: size_t на современных платформах имеет размер 64 бита.

    У вас переполнение. Вы там из 0 вычитаете 1 в итерации цикла, получаете самое большое число, представимое в 64-битном типе.

    Надо переписать цикл на while и делать из него break по достижению 0. Или тип переменной сменить на знаковый.
    Ответ написан
    Комментировать
  • Самопроверка целостности кода контрольной суммой, как реализовать?

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

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Занумеруйте все биты от 0 до 16. Потом транспонируйте эту матрицу. Потом посмотрите на разность результата и конца. Вот эти вот числа - это на сколько бит надо сдвинуть исходные биты, чтобы они встали на нужное место.
    0 1 2 3
    4 5 6 7
    8 9 10 11
    12 13 14 15
    
    0 4 8 12
    1 5 9 13
    2 6 10 13
    3 7 11 15
    
    0 -3 -6 -9
    3 0 -3 -6
    ...


    Все биты с одинаковым смещением можно подсчитать за 3 операции: Сдвиг, битовая маска и побитовое или в ответ.
    Я тут вижу 7 разных чисел -9,-6,-3,0,3,6,9.
    Например, для 0 и 3 у вас будет
    answer = (source & 0x1248) | ((source << 3) | 0x2480) | ...


    Это не 8 пока еще операций, а аж 20. Возможно можно как-то еще их сгруппировать.

    Edit: Возможно, еще подход с таблицей будет быстрее. Для каждого из 16 возможных значений строк выдавайте битовое число - столбец, где эти 4 бита на позициях 0, 4, 8,12. Тогда ответ будет table[source&0xf0] | (table[(source>>4)&0xf] << 1) | (table[(source>>8)&0xf] << 2) | (table[(source>>12)&0xf] << 3).

    Тут 13 битовых операций и 4 чтения из памяти.
    Ответ написан
    2 комментария
  • Ограничения на задачи leetcode какое?

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

    Edit: ах да, они этот список еще меняют иногда. Так что вполне возможно, что вы эту задачу когда-то раньше уже даже решили, но теперь она стала платной.
    Ответ написан
    Комментировать
  • Реализация кэша для мульти поточного приложения?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вам нужна lock-free хеш таблица (гуглите Lock free unordered_map). В стандартной библиотеке таких структур нет. Или просто используйте свои мьютексы при каждом обращении к структуре.
    Ответ написан
    2 комментария
  • Каков принцип взаимодействия stream с программой?

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

    Это целый набор шаблонных классов, которые переопределяют операции побитового сдвига, поэтому у вас в программе используются << и >>. Под капотом это все доходит до системных вызовов, которые пишут или читают данные в системные потоки (pipe). Там тупо команды "запиши вот эти байты" и "отдай мне вот в этот буфер максимум столько-то байт".

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

    При работе с клавиатурой, дайвер клаиватуры получает команды от устройства. Операционная система, зная какое окно сейчас активно, посылает эти команды в поток для нужного окна.
    При работе с сетью, дайвер сетевого устройства получает пакеты, обрабатывает их, передает операционке, она определяет, в какой поток надо эти данные записать, и записывает туда.

    ОС-ка поддерживает список потоков, которые ждут чтения из каждого буфера. Когда что-то в буфер записывается, эти потоки просыпаются.
    Ответ написан
    1 комментарий
  • Зачем передавать функцию как параметр через указатель с++?

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

    Иногда вообще по-другому не сделать. Например, очередь задач. Вот надо вам чтобы в одном потоке выполнялась куча маленьких функций. Тут единственный сопособ - это функцию сохранить в переменную, засунуть в какую-то очередь и потом, когда станет нечего делать, достать ее оттуда и выполнить.

    Или у вас вопрос, почему указатель? Ну ведь фунция - это огромный кусок кода в памяти. Логично же ее передавать как указатель, как и массивы, например. Но тут есть еще и низкоуровневая проблема - в процессоре есть защита от исполнения данных. Без дополнительных танцев с бубном, вы никак данные не выполните, даже если там записан корректный машинный код. Поэтому все функции записаны в read-only секции памяти, специально помеченной, как разрешенная к исполнению. Поэтому единственный сопособ как-то эти данные куда-то передать - это указатель туда. Сами данные-то не перемещаемые.
    Ответ написан
    1 комментарий