![]() |
![]() |
![]() |
|||||||||||||
![]() |
6 алгоритмов решения задач по спортивному программированию |
||||||||||||||
МЕНЮ Искусственный интеллект Поиск Регистрация на сайте Помощь проекту ТЕМЫ Новости ИИ Искусственный интеллект Разработка ИИГолосовой помощник Городские сумасшедшие ИИ в медицине ИИ проекты Искусственные нейросети Слежка за людьми Угроза ИИ ИИ теория Внедрение ИИКомпьютерные науки Машинное обуч. (Ошибки) Машинное обучение Машинный перевод Реализация ИИ Реализация нейросетей Создание беспилотных авто Трезво про ИИ Философия ИИ Big data Работа разума и сознаниеМодель мозгаРобототехника, БПЛАТрансгуманизмОбработка текстаТеория эволюцииДополненная реальностьЖелезоКиберугрозыНаучный мирИТ индустрияРазработка ПОТеория информацииМатематикаЦифровая экономика
Генетические алгоритмы Капсульные нейросети Основы нейронных сетей Распознавание лиц Распознавание образов Распознавание речи Техническое зрение Чат-боты Авторизация |
2018-10-16 14:00 ![]() Ниже мы собрали несколько интересных алгоритмов для решения задач по спортивному программированию, которые можно применить на соревнованиях. Сортировка подсчетом ? наиболее частый способ решения задач по спортивному программированию. Этот алгоритм сортировки работает для данных, ключи которых находятся в некотором известном числовом диапазоне. Его идея заключается в том, чтобы подсчитать количество элементов, соответствующих каждому ключу, и записать это количество в ячейку массива (индекс ячейки ? это ключ, значение ? подсчитанная частота ключа), а после ? вывести элементы нужное количество раз по порядку. Пример: сортировка массива чисел Дан массив чисел и известен числовой диапазон, в котором они располагаются. Например, массив: 1, 4, 1, 2, 7, 5, 2. Нам известно, что эти числа принадлежат промежутку от 0 до 9.
Индекс (ключ): 0 1 2 3 4 5 6 7 8 9 2. Распечатываем каждое число столько раз, сколько мы получили при подсчете: 1 1 2 2 4 5 7 Важно отметить
Пример кода
Shortest Path Faster Algorithm ? это усовершенствованный алгоритм Беллмана-Форда, часто применяющийся на соревнованиях по спортивному программированию. Он вычисляет кратчайшие пути от стартовой вершины до всех остальных во взвешенном ориентированном графе. Считается, что алгоритм хорошо работает на случайных разреженных графах и подходит для графов, содержащих отрицательные веса. Асимптотика SPFA в худшем случае такая же, как у алгоритма Беллмана-Форда (а именно ? O(|V||E|)). Для графов без рёбер отрицательного веса предпочтительнее использовать алгоритм Дейкстры. Основная идея Идея SPFA напоминает идею алгоритма Беллмана-Форда. Каждая вершина используется в качестве кандидата для релаксации смежных вершин. Улучшение по сравнению с последним заключается в следующем: вместо слепой проверки всех вершин, SPFA поддерживает очередь вершин-кандидатов и добавляет вершину в очередь только в том случае, если эта вершина была релаксирована. Процесс повторяется до тех пор, пока не останется вершин, которые могли бы быть релаксированы. Пример кода
Этот алгоритм также известен как алгоритм Косарайю-Шарира. Он решает задачу выявления компонента сильной связности в ориентированном графе и делает это за линейное время. Идея алгоритма опирается на тот факт, что транспонированный граф (направление каждого ребра исходного графа изменено на противоположное) имеет точно такие же сильно связанные компоненты, что и исходный. Алгоритм
Нужно отметить
Z-алгоритм решает задачу поиска всех вхождений некоторого шаблона P в строке S и делает это за линейное время. Z-функция строки Имея строку S длины n на входе, алгоритм составляет Z-массив, в котором Z[i] является длиной наибольшей подстроки, которая начинается в S[i] и также является префиксом S. Далее мы будем называть такую строку подстрокой-префиксом. Вот пример Z-массива: Индекс массива: 0 1 2 3 4 5 6 7 8 9 10 11 Z[1]: 1, потому что длина максимальной по размеру подстроки, начинающейся с этого символа и одновременно являющейся префиксом S, равна 1 ? «а». Z[2]: 0, поскольку S[2] != S[1]. … Z[4]: 3, потому что совпадают S[4:6] и S[0:2]: «aab». Как построить Z-массив? Наивное решение с двумя вложенными циклами, из которых внешний проходит по символам строки, а внутренний ищет длину наибольшей подстроки-префикса S, имеет квадратичную сложность. Как построить Z-массив за линейное время? Идея заключается в следующем: в течение работы алгоритма мы храним интервал [L, R] такой, что 1 ? L ? i ? R, а S[L, R] ? это самая правая подстрока-префикс S. На шаге i = 1 мы можем сосчитать L и R, просто сравнив S[0…] и S[1…] (и заодно получив значение Z[1]).
Пример кода
И где тут pattern searching? Внимательный читатель заметит, что в алгоритме выше никак не фигурирует поиск паттернов. Для решения этой задачи сделаем хитрость: составим новую строку Sn = P + $ + S, где P ? паттерн; $ ? символ-разделитель, который не встречается ни в P, ни в S; S ? исходная строка и вычислим Z-массив для Sn. Нетрудно заметить, что если Z[i] = length(P), то паттерн входит в эту строку начиная с символа i. k-мерное дерево имеет множество применений, но мы рассмотрим его в контексте эффективного решения задачи поиска ближайшего соседа в k-мерном пространстве. Пример: построение k-d дерева Для простоты возьмем двумерную плоскость и предположим, что нам дан следующий набор точек: (2,3), (5,4), (9,6), (8,1), (7,2). Во время выполнения алгоритма строится бинарное дерево, которое на каждом этапе рекурсии делит пространство на 2 части.
Повторяем приведенные выше шаги, меняя разделяющую ось. Мы получим вот такое дерево: А если изобразить алгоритм выше на плоскости, получится вот такая картина: Поиск ближайшего элемента (nearest neighbour) Заключительный алгоритм решения задач по спортивному программированию: дано множество точек, мы хотим эффективно находить ближайшую точку этого множества к некоторой данной нам точке (будем называть ее исходной).
Пример кода: построение k-d дерева
Важно отметить
Источники: Алгоритмы для соревнования по спортивному программированию on Quora; советы по спортивному программированию by Rohan Verma Источник: proglib.io ![]() Комментарии: |
||||||||||||||