Алгоритмы и структуры данных, семинар группы 158-2 — различия между версиями

Материал из Wiki - Факультет компьютерных наук
Перейти к: навигация, поиск
(Добавил семинары за 12.01 и 14.01)
(Домашние задания)
 
(не показано 79 промежуточных версии этого же участника)
Строка 1: Строка 1:
==Правила игры==
+
Текущие результаты могут быть найдены
 +
[https://docs.google.com/spreadsheets/d/1Zv-qcOHHZyPKgA3AfpbQaxmTXiHF9FD9kiGb4aJNIaI/edit?usp=sharing здесь].
  
 +
==Правила игры==
 
В основном все общение будет происходить с семинаристом курса, однако к проверке работы также будет привлекаться и учебный ассистент.
 
В основном все общение будет происходить с семинаристом курса, однако к проверке работы также будет привлекаться и учебный ассистент.
 
Если у студента есть некоторые разногласия с ассистентом, то он всегда может обратиться к семинаристу, чтобы разрешить конфликт.
 
Если у студента есть некоторые разногласия с ассистентом, то он всегда может обратиться к семинаристу, чтобы разрешить конфликт.
Строка 22: Строка 24:
 
В ходе курса студентам будут предложены пять домашних заданий, практическая контрольная работа, а в заключении итоговый экзамен.
 
В ходе курса студентам будут предложены пять домашних заданий, практическая контрольная работа, а в заключении итоговый экзамен.
 
Также в течении семестра необходимо активно участвовать в семинарах, решая задачки и выполняя практические упражнения, предусмотренные для самостоятельной работы.
 
Также в течении семестра необходимо активно участвовать в семинарах, решая задачки и выполняя практические упражнения, предусмотренные для самостоятельной работы.
 +
 +
===Домашние задания===
 +
Домашнее задание делится на две части.  Теоретическая, сводится к решению задач. Решение необходимо отправлять в виде pdf на почту семинаристу, а также можно приносить на листочках на семинар, если это оговорено заранее. Практическая, предусматривает сдачу задачи в контест. Также вы должны прислать семинаристу pdf с обоснованием правильности работы алгоритма и оценкой сложности. При этом на семинаре вы должны защитить одну из задач.
 +
 +
Если я хочу прислать решение по 1-му домашнему заданию, а меня зовут Симагин Денис, то тема письма должна выглядеть так:
 +
<center>
 +
    H1 - Симагин Денис.
 +
</center>
  
 
===Семинары===
 
===Семинары===
 
Вся ваша деятельность на семинарах делится на две части. Работа на семинаре и решение упражнений, которые вам даны для самостоятельного рассмотрения дома. Вы получаете плюсики за  каждое решеное упражнение, а также за активное участие в семинаре, обычно это разбор небольшой задачи у доски (не более одного плюсика за занятие).
 
Вся ваша деятельность на семинарах делится на две части. Работа на семинаре и решение упражнений, которые вам даны для самостоятельного рассмотрения дома. Вы получаете плюсики за  каждое решеное упражнение, а также за активное участие в семинаре, обычно это разбор небольшой задачи у доски (не более одного плюсика за занятие).
  
Упражнения стоит присылать на почту семинаристу, при этом тема письма должна строго удовлетворять формату. К примеру, меня зовут Симагин Денис и я хочу отправить задачу с первого семинар, тогда заголовок письма должен иметь вид
+
Упражнения стоит присылать на почту семинаристу, при этом тема письма должна строго удовлетворять формату. К примеру, меня зовут Симагин Денис и я хочу отправить задачу с первого семинара, тогда заголовок письма должен иметь вид
 
<center>
 
<center>
     A12.01: Разворот списка - Симагин Денис.
+
     A01.21: Разворот списка - Симагин Денис.
 
</center>
 
</center>
 +
 +
Объединять несколько решений в одном письме нельзя, это лишь создаст путаницу в обсуждении. При нарушении правил семинарист не дает гарантий, что решение будет проверено.
  
 
===Формула оценки===
 
===Формула оценки===
Строка 50: Строка 62:
 
     O<sub>Итоговая</sub> =  0.3·О<sub>Экзамена</sub> + 0.7·О<sub>Накопленная</sub>.
 
     O<sub>Итоговая</sub> =  0.3·О<sub>Экзамена</sub> + 0.7·О<sub>Накопленная</sub>.
 
</center>
 
</center>
 +
 +
==Домашние задания==
 +
===Задание H1===
 +
# [https://www.dropbox.com/s/1u5bk81edt6a1io/asymtotic_homework.pdf?dl=0&preview=asymtotic_homework.pdf Первая часть] (16 февраля, 9:00)
 +
# [https://www.dropbox.com/s/gwxvf34gg6nt4fe/recurrent_homework.pdf?dl=0&preview=recurrent_homework.pdf Вторая часть] (16 февраля, 9:00)
 +
# [https://official.contest.yandex.ru/contest/2183/enter/ Контест] (20 февраля, 20:00), [https://github.com/dasimagin/Algo2016/tree/master/A02.25 решение].
 +
 +
Распределение задач [https://docs.google.com/spreadsheets/d/1Zv-qcOHHZyPKgA3AfpbQaxmTXiHF9FD9kiGb4aJNIaI/edit#gid=1070813601 здесь].
 +
 +
===Задание H2===
 +
 +
# [https://official.contest.yandex.ru/contest/2191/enter/ Контест] на динамику, дедлайн (2 марта, 20:00), [https://github.com/dasimagin/Algo2016/tree/master/A03.03 решение].
 +
# [https://official.contest.yandex.ru/contest/2262/enter/ Контест] на графы, дедлайн (14 марта, 20:00).
 +
Распределение задач можно найти [https://docs.google.com/spreadsheets/d/1Zv-qcOHHZyPKgA3AfpbQaxmTXiHF9FD9kiGb4aJNIaI/edit#gid=1070813601 здесь].
 +
 +
===Задание H3===
 +
# [https://official.contest.yandex.ru/contest/2290/enter/ Контест] на кратчайшии пути, дедлайн (3 апреля, 20:00), [https://github.com/dasimagin/Algo2016/tree/master/A04.05 [решение]].
 +
# [https://official.contest.yandex.ru/contest/2370/enter/ Контест] на хеширование, дедлайн (26 апреля, 20:00), [https://github.com/dasimagin/Algo2016/tree/master/A05.10 [решение]].
 +
Распределение задач можно найти [https://docs.google.com/spreadsheets/d/1Zv-qcOHHZyPKgA3AfpbQaxmTXiHF9FD9kiGb4aJNIaI/edit#gid=1070813601 здесь].
 +
 +
===Задание H4===
 +
# [https://official.contest.yandex.ru/contest/2473/enter/ Контест] сборная солянка  (22 мая, 23:59), [решение].
 +
Распределение задач можно найти [https://docs.google.com/spreadsheets/d/1Zv-qcOHHZyPKgA3AfpbQaxmTXiHF9FD9kiGb4aJNIaI/edit#gid=1070813601 здесь].
 +
 +
===Задание H5===
 +
# [https://www.dropbox.com/s/eo688wfmq9qg8a3/dfa.pdf?dl=0 Листочек с теорией] на конечные автоматы и регулярные языки  (4 июня, 23:59), [решение].
 +
Распределение задач можно найти [https://docs.google.com/spreadsheets/d/1Zv-qcOHHZyPKgA3AfpbQaxmTXiHF9FD9kiGb4aJNIaI/edit#gid=1070813601 здесь].
  
 
==Семинары==
 
==Семинары==
  
===Семинар A12.01===
+
===Семинар A05.10===
# Знакомство с группой.
+
Оперативно разбирали темы, необходимые для домашней работы.
# Рассмотрение примеров использования рекурсии.
+
  
====Факториал====
+
# Поговорили о жадном алгоритме декодирования [https://en.wikipedia.org/wiki/Prefix_code префиксного кодирования]. Для этого вам может потребоваться [https://en.wikipedia.org/wiki/Trie бор]. Кстати, классическим примером префиксного кодирования является [https://en.wikipedia.org/wiki/Huffman_coding код Хаффмана].
Предложить рекурсивный вариант вычисления факториала.
+
# Поговорили о [https://en.wikipedia.org/wiki/Disjoint-set_data_structure системе непересекающихся множеств]. На семинаре была дана только верхняя оценка работы.
 +
# Повторили [https://en.wikipedia.org/wiki/Binary_heap двоичные кучи].
 +
 
 +
===Семинар A04.26===
 +
Сегодня был только один человек на семинаре, да и то с большим опозданием.
 +
 
 +
====Рассмотренные вопросы====
 +
# [https://en.wikipedia.org/wiki/Segment_tree Дерево отрезков].
 +
# Кратко о [http://en.cppreference.com/w/cpp/language/exceptions исключениях] и как их [http://en.cppreference.com/w/cpp/language/throw бросать].
 +
# Когда и почему инвалидируются [http://en.cppreference.com/w/cpp/iterator итераторы].
 +
# Что значит [http://en.cppreference.com/w/cpp/language/member_functions спецификатор const] для методов функций.
 +
 
 +
==== максимальный по сумме подмассив (упражнение, 10 мая)====
 +
Дан массив целых чисел (положительных и отрицательных). Предложите структуру, позволяющую находить максимальный по сумме подмассив внутри указанной части исходного массива. Сложность O(log N), где N - размер массива.
 +
<div align="right">[http://e-maxx.ru/algo/segment_tree [Описание алгоритма]]</div>
 +
<br>
 +
:'''Re:''' Адаптируйте дерво отрезков для этих целей.
 +
 
 +
==== Ближайший общий предок (упражнение, 10 мая)====
 +
Дано бинарное дерево поиска. Предложите структуру, которая за O(log N) действий позволяет найти ближайшего общего предка для двух узлов. N - количество узлов в дереве.
 +
<div align="right">[http://e-maxx.ru/algo/lca [Описание алгоритма]]</div>
 +
<br>
 +
:'''Re:''' Попробуйте предобработать дерево, построив дерево отрезков во время обхода (сложность O(n)).
 +
 
 +
===Семинар A04.21===
 +
Продолжили разговор о [https://ru.wikipedia.org/wiki/Двоичное_дерево_поиска деревьях поиска].
 +
 
 +
====Рассмотренные вопросы====
 +
# Сравнение деревьев бинарного поиска и хешей (краткий ответ можно найти [http://cs.stackexchange.com/questions/270/hash-tables-versus-binary-trees здесь]).
 +
# Обходы деревьев (почитать можно [https://en.wikipedia.org/wiki/Tree_traversal#Other_types здесь]).
 +
# Оценка сложности работы деревьев.
 +
 
 +
====Ссылки для дополнительного чтения====
 +
# [https://en.wikipedia.org/wiki/AVL_tree АВЛ-дерево].
 +
# [https://en.wikipedia.org/wiki/Splay_tree Расширяющееся дерево] (описаны только в 2м издании Кормена).
 +
# [https://en.wikipedia.org/wiki/B-tree B-дерево] (хорошо описаны в Кормене).
 +
# [https://en.wikipedia.org/wiki/Random_binary_tree Случайные деревья] (тема раскрыта в Кормене).
 +
 
 +
 
 +
 
 +
===Семинар A04.19===
 +
Поговорили о бинарных деревьях поиска, кратку справку можно получить [https://ru.wikipedia.org/wiki/Двоичное_дерево_поиска здесь].
 +
 
 +
====Какие операции надо знать====
 +
# Вставка, удаление.
 +
# Поиск по ключу
 +
# Поиск минимального/максимального ключа.
 +
# Поиск предыдущего/последующего ключа.
 +
 
 +
====Ссылки для чтения====
 +
# [https://en.wikipedia.org/wiki/Return_value_optimization Return value optimization].
 +
# Умные указатели: [http://en.cppreference.com/w/cpp/memory/unique_ptr unique], [http://en.cppreference.com/w/cpp/memory/shared_ptr shared] и [http://en.cppreference.com/w/cpp/memory/weak_ptr weak].
 +
 
 +
===Семинар A04.14===
 +
''Занятия не было.''
 +
 
 +
===Семинар A03.14===
 +
''Занятия не было.''
 +
 
 +
====Программа для робота====
 +
Наш робот стоит в клетке A квадратного поля.  На каких-то клетка стоят ящики и поэтому робот не может на них встать. Напишите для робота программу, которая строила бы оптимальный путь до каждой доступной клетки.
 +
<hr>
 +
:'''Re:''' Используйте поиск в ширину.
 +
 
 +
====Компоненты связаности====
 +
Предложите алгоритм, который подсчитывает число компонент связаности. А как вывести номера вершин для каждой компоненты?
 +
<hr>
 +
:'''Re:''' Используйте поиск в глубину.
 +
 
 +
====Задачка от Смбата====
 +
Есть некоторый граф и указаны две вершины A и B. Предложите алгоритм, который выводит все ребра, через которые проходит хотя бы один оптимальный путь из
 +
A в В. Граф не ориентированный.
 +
<hr>
 +
:'''Re:''' Используйте поиск в ширину.
 +
 
 +
 
 +
====Двудольный граф====
 +
Проверить, является ли предложенный граф [https://en.wikipedia.org/wiki/Bipartite_graph двудольным].
 +
<br>
 +
:'''Re:''' Используйте поиск в ширину.
 +
 
 +
====Диаметр (упражнение, 15 марта, 9:00)====
 +
Предложите алгоритм, находящий диаметр неориентированного графа.
 +
 
 +
====Предок (упражнение, 15 марта, 9:00)====
 +
Дано бинарное дерево поиска. Предложите алгоритм, который за O(1) позволяет ответить, является ли вершина A предком для вершины B.
 +
:'''Re:''' На предобработку дерева допускается использовать O(|E| + |V|).
 +
 
 +
 
 +
===Семинар A03.03===
 +
 
 +
====Хранение графов (Упражнения)====
 +
# Граф хранится в виде списков смежности. Сколько нужно действий, чтобы узнать количество исходящих ребер из вершины? А входящих?
 +
# Что произойдет с матрицей смежности ориентированного графа, если обратить все ребра. Как обратить ребра, если используется список смежности? Какое количество операций требуется?
 +
# Покажите, что O(|V|) с помощью матрицы смежности можно обнаружить вершину, из которой не исходит ни одного ребра, но при этом есть ребра из все оставшихся вершин в нее.
 +
 
 +
===Семинар A03.01===
 +
# Поговорили про реализацию сложения в длинной арифметике.
 +
# Поговорили о ключевом слове [http://en.cppreference.com/w/cpp/language/explicit explicit] и [http://en.cppreference.com/w/cpp/language/implicit_cast преобразовании типов]. Подробнее об этом [http://en.cppreference.com/w/cpp/language/expressions#Conversions здесь].
 +
# Поговорили о том, как графы хранятся в памяти, прочитать можно [https://en.wikipedia.org/wiki/Graph_(abstract_data_type) здесь].
 +
 
 +
===Семинар A02.25===
 +
# Провели защиту решений из контеста H1,  примеры реализации можно посмотреть [https://github.com/dasimagin/Algo2016/tree/master/A02.25 здесь].
 +
# Поговорили о [https://en.wikipedia.org/wiki/Dynamic_programming#Dynamic_programming_in_computer_programming типах динамики].
 +
 
 +
===Семинар A02.18===
 +
Разобрали теоретическую часть H1.
 +
 
 +
====Максимальная неунывающая подпоследовательность====
 +
Дан массив целых чисел. Помогите неунывающей студентке Ане найти длину максимальной неубывающей подпоследовательности.
 +
К примеру, для набора [1 2 3 1 4] это  будет [1 2 3 4], а для  [0 2 0 2 0 2] есть несколько вариантов [0 0 0 2], [0 0 2 2], [ 0 2 2 2].
 +
Вам же нужно вывести только длину.
 +
<div align="right">[https://en.wikipedia.org/wiki/Longest_increasing_subsequence [Описание алгоритма]]</div>
 +
 
 +
====Задача о порядке перемножения матриц====
 +
Дана последовательность матриц, которую нужно перемножить,  A · B · ... · C. Требуется минимизировать количество скалярных операций для вычисления их произведения. Матрицы предполагаются совместимыми по отношению к матричному умножению.
 +
<div align="right">[https://en.wikipedia.org/wiki/Matrix_chain_multiplication [Описание алгоритма]]</div>
 +
 
 +
====Задача о монетках (Упражнение, 1 марта, 9:00)====
 +
Вам предлагается решить познакомиться с ресурсом [https://www.hackerrank.com hackerrank] и решить следующую [https://www.hackerrank.com/challenges/coin-change задачу].
 +
<div align="right">[https://github.com/dasimagin/Algo2016/blob/master/A02.18/coins.cpp [Решение]]</div>
 +
 
 +
===Семинар A02.16===
 +
Разобрали теоретическую часть H1.
 +
 
 +
===Семинар A02.11===
 +
Рассмотрели следующие темы:
 +
# Алгоритм нахождения k-й статистики за O(n) в среднем.
 +
# Алгоритм нахождения k-й статистики с гарантированной сложностью O(n).
 +
# Алгоритм нахождения двух ближайших точек на плоскости за O(n log n).
 +
 
 +
====Медианы и квантили====
 +
В математической статистике часто необходимо вычислить [https://ru.wikipedia.org/wiki/Медиана_(статистика) медиану]
 +
для случайной величины или [https://ru.wikipedia.org/wiki/Квантиль квантиль]. Для этого удобно применять k-статистики.
 +
В частности для n реализаций некоторой случайной величины для фиксированного p можно найти x, что P[X < x] = p, как значение [pn] статистики.
 +
 
 +
====Треугольник с минимальным периметром====
 +
Среди заданного множества точек выбрать три различных точки так, чтобы сумма попарных расстояний между ними была наименьшей.
 +
<hr>
 +
:'''Re:''' Задача поиска пары ближайших точек может быть сведена к задаче о треугольнике с минимальным периметром. Подробное решение можно найти [https://code.google.com/codejam/contest/311101/dashboard#s=a&a=1 здесь].
 +
 
 +
====Минимальная сумма====
 +
Вам задан набор из n векторов на плоскости. Для каждого вектора разрешается домножить любые его координаты на -1.
 +
Вам нужно найти два вектора из набора и определить, какие из их координат следует умножить на -1 таким образом, чтобы модуль суммы полученных векторов был минимально возможным. Более подробное условие можно найти [http://codeforces.com/contest/120/problem/J здесь].
 +
<hr>
 +
:'''Re:''' Минимальная сумма для произвольных двух векторов (x1, y1) и (x2, y2) может быть получена следующим образом (|x1| - |x2|, |y1| - |y2|). А дальше задача сводится к поиска ближайших двух точек.
 +
 
 +
====n-th element (упражнение, 25 февраля)====
 +
Реализуйте линейный алгоритм нахождения n-й статистики.
 
<div align="right">[Решение]</div>
 
<div align="right">[Решение]</div>
 
<hr>
 
<hr>
:'''Re:''' Очевидно, что предложенная рекурсивная реализация факториала не является хвостовой рекурсией, однако существует итерационная версия алгоритма. Поэтому наличие хвостовой рекурсии является достаточным, но не обходимым условием наличия итерационного алгоритма.
+
:'''Re:''' Допускается реализация алгоритма работающего за O(n) в среднем. В стандартной библиотеке есть схожий [http://en.cppreference.com/w/cpp/algorithm/nth_element алгоритм]. Изучите следующий [http://e-maxx.ru/algo/kth_order_statistics материал].
  
====Фибоначчи====
+
====3 vs 7 (упражнение*, 25 февраля)====
Предложить рекурсивный вариант вычисления чисел Фибоначчи.
+
Можно ли в алгоритме, находящем, n-й элемент с гарантированной линейной сложность вместо 5-ок объектов использовать 3-ки? А 7-ки? Ответ обоснуйте.
 
<div align="right">[Решение]</div>
 
<div align="right">[Решение]</div>
 
<hr>
 
<hr>
:'''Re:''' Показан пример сведения множественной рекурсии к одиночной.
+
:'''Re:''' Для решения воспользуйтесь доказательством сложности алгоритма из книги Кормана.
  
====Степень====
+
====Ближайшие точки (упражнение, 25 февраля)====
Предложить рекурсивный алгоритм вычисления неотрицательной степени числа.
+
Реализуйте алгоритм нахождения двух ближайших точек на плоскости.
 
<div align="right">[Решение]</div>
 
<div align="right">[Решение]</div>
 +
<hr>
 +
:'''Re:''' Изучите следующий [http://e-maxx.ru/algo/nearest_points материал].
  
====Разворот списка (упражнение)====
+
===Семинар A02.04===
Реализовать рекурсивную функцию reverse, которая обращает связи [https://en.wikipedia.org/wiki/Linked_list#Singly_linked_list односвязанного списка] в противоположную сторону.
+
Рассмотрели следующие методы решения рекуррентных соотношений:
Таким образом последний элемент списка становится первым, предпоследний вторым, и т.д.
+
# Индукция
Пусть список имеет вид [1, 2, 3, 4, 5], тогда после применения функции reverse он должен выглядеть, как [5, 4, 3, 2, 1].
+
# Раскрытие суммы
 +
# Рекурсивное дерево
 +
# [https://en.wikipedia.org/wiki/Master_theorem Основная теорема].
 +
 
 +
====Binary search (упражнение, 11 февраля)====
 +
В качестве тренировки предлагаю вам для бинарного поиска проделать все то же самое, что мы делали на семинаре для merge sort:
 +
# Получить рекуррентную зависимость и применить основную теорему.
 +
# Доказать оценку по индукции
 +
# Раскрыть через сумму
 +
# Доказать через дерево рекурсии.
 +
<div align="right">[Решение]</div>
 +
 
 +
===Семинар A02.02===
 +
# Провели контрольную работу, разбор можно найти [https://github.com/dasimagin/Algo2016/blob/master/A02.02/test.pdf здесь].
 +
# Порешали задачи на рекуррентные зависимости.
 +
 
 +
===Семинар A01.28===
 +
# Поговорили о том, что значит оценки сложности в жизни.
 +
# Разобрали [https://en.wikipedia.org/wiki/Counting_sort сортировку подсчетом] и [https://en.wikipedia.org/wiki/Radix_sort разрядную сортировку].
 +
# Начали осваивать рекуррентные соотношения.
 +
 
 +
====Radix sort (упражнение, 4 февраля)====
 +
Реализуйте поразрядную сортировку для 64-битных чисел, один разряд -- это один байт (для этого вам придется реализовать сортировку подсчетом).
 +
<div align="right">[https://github.com/dasimagin/Algo2016/blob/master/A01.28/radix_sort.cpp [Решение]]</div>
 +
<hr>
 +
:'''Re:''' Реализация только сортировки подсчетом стоит 1 балл.
 +
 
 +
===Семинар A01.26===
 +
# Немного поговорили о задаче [https://en.wikipedia.org/wiki/External_sorting внешней сортировки].
 +
# Разобрали [https://github.com/dasimagin/Algo2016/blob/master/A01.26/o-notation-exercices.pdf упражнения] на о-нотацию.
 +
# Посмотрели примеры использования сортировок.
 +
 
 +
====Равные массивы====
 +
Дано два массива чисел размера n, определить, являются ли эти массивы одинаковыми с точностью до перестановки элементов.
 +
:'''Re:''' Отсортируем массивы, теперь для проверки достаточно пройтись параллельно по обоим массивам, проверяя, что соответствующие элементы совпадают. Сложность алгоритма n log n. Эта идея используется, к примеру, [http://en.cppreference.com/w/cpp/algorithm/set_difference здесь].
 +
 
 +
====Уникальные элементы====
 +
Дан массив чисел длины n, как проверить, что все ли элементы в массиве уникальны?
 +
:'''Re:''' Отсортируем массив, теперь для проверки достаточно пройтись по массиву, проверяя, равны ли соседние элементы. Сложность алгоритма n log n.  Эта идея используется, к примеру, [http://en.cppreference.com/w/cpp/algorithm/unique здесь].
 +
 
 +
====Разбиение на пары====
 +
Дан массив чисел размера 2n, как определить, можно ли разбить массив чисел на пары, которые дают сумму 1997.
 +
:'''Re:''' Отсортируем массив, теперь достаточно проверить, что для всех k < n выполняется a[k] + a[2n - k - 1] = 1997. Сложность алгоримат n log n.
 +
 
 +
====Площадь наложения====
 +
На числовой прямой окрасили n отрезков. Известны координаты левого и правого концов каждого отрезка (целые числа). Найти длину окрашенной части числовой прямой.
 +
:'''Re:''' Отсортируем концы отрезков (2n штука) по координатам, если координаты совпадают, то левый конец больше правого.  Теперь за одни проход концов можно вычислить закрашенную площадь. Для этого достаточно завести счетчик, указывающий количество отрезков, накрывающих следующий сегмент, и поддерживать его состояние. Сложность алгоримат n log n.
 +
 
 +
====Задачи на О-нотацию (упражнение, 2 февраля)====
 +
Листочек с упражнениями можно найти [https://github.com/dasimagin/Algo2016/blob/master/A01.26/o-notation-tasks.pdf здесь], на семинаре (A01.28) можно будет задавать по нему вопросы.
 +
<div align="right">[https://github.com/dasimagin/Algo2016/blob/master/A01.26/o-notation-solutions.pdf [Решение]]</div>
 +
 
 +
===Семинар A01.21===
 +
# Закончили разбор сортировки [https://github.com/dasimagin/Algo2016/blob/master/A01.19/in-place-merge-sort.pdf in-place merge]
 +
# Поговорили о [https://en.wikipedia.org/wiki/Quicksort quick sort], особое внимание уделили [https://en.wikipedia.org/wiki/Quicksort#Choice_of_pivot выбору опорного элемента].
 +
# Начали говорить о [https://en.wikipedia.org/wiki/Big_O_notation#Big_Omega_notation О-символике]
 +
 
 +
====В чем разница между O(f) и o(f)====
 +
Материал доступен [https://github.com/dasimagin/Algo2016/blob/master/A01.19/o-notation.pdf здесь].
 +
 
 +
====Quick sort (упражнение, 28 января)====
 +
Реализуйте сортировку qiuck sort.
 +
<div align="right">[https://github.com/dasimagin/Algo2016/blob/master/A01.21/quick_sort.cpp [Решение]]</div>
 +
<hr>
 +
:'''Re:''' В качестве решения приведена комбинация quick sort и insertion sort. Замеры производительности можно посмотреть [https://github.com/dasimagin/Algo2016/blob/master/A01.21/timing.txt здесь].
 +
 
 +
===Семинар A01.19===
 +
# [https://en.wikipedia.org/wiki/Insertion_sort Insert sort]
 +
# [https://en.wikipedia.org/wiki/Merge_sort Merge sort]
 +
# [https://github.com/dasimagin/Algo2016/blob/master/A01.19/in-place-merge-sort.pdf in-place merge sort]
 +
 
 +
====Insertion sort====
 +
Реализуйте сортировку вставками.
 +
<div align="right">[https://github.com/dasimagin/Algo2016/blob/master/A01.19/insert-sort.cpp [Решение Смбата]]</div>
 +
<hr>
 +
 
 +
====External sorting (упражнение, 26 января)====
 +
У студента Никиты есть компьютер, оперативная память которого может хранить M чисел и имеет небольшой буфер. На диске у этого компьютера хранится массив размером 100M чисел и имеется еще куча свободного места. Предложите Никите алгоритм, с помощью которого он мог бы отсортировать свой массив.
 +
<div align="right">[https://en.wikipedia.org/wiki/External_sorting [Решение]]</div>
 +
<hr>
 +
:'''Re:''' Подумайте, какие известные сортировки вы можете применить.
 +
 
 +
====Merge sort (упражнение, 28 января)====
 +
Реализуйте сортировку слиянием.
 +
<div align="right">[https://github.com/dasimagin/Algo2016/blob/master/A01.19/merge_sort.cpp [Решение]]</div>
 +
<hr>
 +
:'''Re:''' Для зачета вы должны пройти все тесты в [https://contest.yandex.ru/contest/2007 контесте]. За задачу вы получите два плюсика, реализовав функцию [https://official.contest.yandex.ru/contest/2007/problems/C/ merge] и функцию [https://official.contest.yandex.ru/contest/2007/problems/D/ merge_sort]. Код семинаристу стоит присылать только после того, как пройдены все тесты. Сначала присылайте первую задача, а затем уже саму сортировку.
 +
 
 +
====In-place merge sort (упражнение, 28 января)====
 +
Студентка Таня очень любит читать Хабр. В одном из постов она натолкнулся на [https://github.com/dasimagin/Algo2016/blob/master/A01.19/in-place-merge-sort.pdf описание алгоритма], который позволяет применять сортировку слиянием без использования дополнительной памяти. Помогите Тане оценить сложность работы алгоритма.
 +
<div align="right">[https://github.com/dasimagin/Algo2016/blob/master/A01.19/in-place-merge-sort-complexity.pdf [Решение Никиты]]</div>
 
<hr>
 
<hr>
:'''Re''': Кстати, Кроме рекурсивных функций принято еще выделять и рекурсивные структуры данных, к примеру [https://en.wikipedia.org/wiki/Linked_list списки] и [https://en.wikipedia.org/wiki/Binary_tree деревья]. В качестве подсказки воспользуйтесь итеративной версией функции, предложенной ниже.
+
:'''Re:''' Задача стоит 2 плюсика.
<div align="right">[https://yadi.sk/d/WLEAtqVxmwKVq [Подсказка]] [Решение]</div>
+
  
===Семинар A14.01===
+
===Семинар A01.14===
 
# Множественная и одиночная рекурсии.
 
# Множественная и одиночная рекурсии.
 
# Стек и куча.
 
# Стек и куча.
Строка 92: Строка 369:
 
====01 строки====
 
====01 строки====
 
Предложить рекурсивный алгоритм, выводящий всевозможные строки длины n из 0 и 1 в [https://en.wikipedia.org/wiki/Lexicographical_order лексикографическом порядке].
 
Предложить рекурсивный алгоритм, выводящий всевозможные строки длины n из 0 и 1 в [https://en.wikipedia.org/wiki/Lexicographical_order лексикографическом порядке].
<div align="right">[Решение]</div>
+
<div align="right">[https://github.com/dasimagin/Algo2016/blob/master/A01.14/strings.cpp [Решение]]</div>
 
<hr>
 
<hr>
 
:'''Re''': В решении продемонстрированы все основные [https://en.wikipedia.org/wiki/Recursion_(computer_science)#Implementation_issues особенности] реализации рекурсивных функций.
 
:'''Re''': В решении продемонстрированы все основные [https://en.wikipedia.org/wiki/Recursion_(computer_science)#Implementation_issues особенности] реализации рекурсивных функций.
Строка 98: Строка 375:
 
====Бинарный поиск====
 
====Бинарный поиск====
 
Предложить рекурсивный алгоритм, производящий [https://en.wikipedia.org/wiki/Binary_search_algorithm бинарный поиск] элемента в отсортированном массиве.  
 
Предложить рекурсивный алгоритм, производящий [https://en.wikipedia.org/wiki/Binary_search_algorithm бинарный поиск] элемента в отсортированном массиве.  
<div align="right">[Решение Тани]</div>
+
<div align="right">[https://github.com/dasimagin/Algo2016/blob/master/A01.14/search.cpp [Решение]]</div>
 
<hr>
 
<hr>
:'''Re''': Метод олицетворят подход [https://en.wikipedia.org/wiki/Divide_and_conquer_algorithms разделяй и властвуй].
+
:'''Re''': Метод олицетворят подход [https://en.wikipedia.org/wiki/Divide_and_conquer_algorithms разделяй и властвуй]. В качестве примера приведена рекурсивная реализация на шаблонах, хотя это не оптимальный подход.
  
 
====Ханойская башня - 1====
 
====Ханойская башня - 1====
 
Предложить рекурсивную функцию, печатающую последовательность перемещений (в формате (x, y), где x и y — номера стержней, с которого и на который перемещается диск), являющуюся решением задачи о Ханойской башне.
 
Предложить рекурсивную функцию, печатающую последовательность перемещений (в формате (x, y), где x и y — номера стержней, с которого и на который перемещается диск), являющуюся решением задачи о Ханойской башне.
<div align="right">[Решение Свята]</div>
+
<div align="right">[https://github.com/dasimagin/Algo2016/blob/master/A01.14/hanoi-1.cpp [Решение Свята]]</div>
  
 
====Алгоритм Евклида (упражнение)====
 
====Алгоритм Евклида (упражнение)====
Реализовать рекурсивную версию [https://en.wikipedia.org/wiki/Euclidean_algorithm| алгоритма Евклида] для нахождения наибольшего общего делителя.
+
Реализовать рекурсивную версию [https://en.wikipedia.org/wiki/Euclidean_algorithm алгоритма Евклида] для нахождения наибольшего общего делителя.
<div align="right">[Решение]</div>
+
<div align="right">[https://github.com/dasimagin/Algo2016/blob/master/A01.14/euclid.cpp [Решение Никиты]]</div>
 
<hr>
 
<hr>
 
:'''Re''': При правильном решении вы должны получить [https://en.wikipedia.org/wiki/Recursion_(computer_science)#Tail-recursive_functions хвостовую рекурсию].
 
:'''Re''': При правильном решении вы должны получить [https://en.wikipedia.org/wiki/Recursion_(computer_science)#Tail-recursive_functions хвостовую рекурсию].
Строка 122: Строка 399:
 
# []
 
# []
 
# [1]
 
# [1]
<div align="right">[Решение]</div>
+
<div align="right">
 +
[https://github.com/dasimagin/Algo2016/blob/master/A01.14/hanoi-2-sviatoslav.cpp [Решение Святослава]]
 +
[https://github.com/dasimagin/Algo2016/blob/master/A01.14/hanoi-2.cpp [Решение]]
 +
</div>
 +
<hr>
 +
:'''Re:''' Для решения используйте задачу разобранную на семинре. Стержни можно смоделировать с помощью  [http://en.cppreference.com/w/cpp/container/vector вектора].
 +
 
 +
===Семинар A01.12===
 +
# Знакомство с группой.
 +
# Рассмотрение примеров использования рекурсии.
 +
 
 +
====Факториал====
 +
Предложить рекурсивный вариант вычисления факториала.
 +
<div align="right">[https://github.com/dasimagin/Algo2016/blob/master/A01.12/factorial.cpp [Решение]]</div>
 +
<hr>
 +
:'''Re:''' Очевидно, что предложенная рекурсивная реализация факториала не является хвостовой рекурсией, однако существует итерационная версия алгоритма. Поэтому наличие хвостовой рекурсии является достаточным, но не обходимым условием наличия итерационного алгоритма с использованием константной памяти.
 +
 
 +
====Фибоначчи====
 +
Предложить рекурсивный вариант вычисления чисел Фибоначчи.
 +
<div align="right">[https://github.com/dasimagin/Algo2016/blob/master/A01.12/fibonacci.cpp [Решение]]</div>
 +
<hr>
 +
:'''Re:''' Показан пример сведения множественной рекурсии к одиночной.
 +
 
 +
====Степень====
 +
Предложить рекурсивный алгоритм вычисления неотрицательной степени числа.
 +
<div align="right">[https://github.com/dasimagin/Algo2016/blob/master/A01.12/power.cpp [Решение]]</div>
 +
 
 +
====Разворот списка (упражнение)====
 +
Реализовать рекурсивную функцию reverse, которая обращает связи [https://en.wikipedia.org/wiki/Linked_list#Singly_linked_list односвязанного списка] в противоположную сторону.
 +
Таким образом последний элемент списка становится первым, предпоследний вторым, и т.д.
 +
Пусть список имеет вид [1, 2, 3, 4, 5], тогда после применения функции reverse он должен выглядеть, как [5, 4, 3, 2, 1].
 
<hr>
 
<hr>
:'''Re:''' Для решения используйте задачу разобранную на семинре. Стержни можно смоделировать с помощью  [http://en.cppreference.com/w/cpp/container/stack стека].
+
:'''Re''': Кстати, кроме рекурсивных функций принято еще выделять и рекурсивные структуры данных, к примеру [https://en.wikipedia.org/wiki/Linked_list списки] и [https://en.wikipedia.org/wiki/Binary_tree деревья].
 +
<div align="right">[https://github.com/dasimagin/Algo2016/blob/master/A01.12/reverse.cpp [Решение]]</div>

Текущая версия на 14:19, 1 июня 2016

Текущие результаты могут быть найдены здесь.

Содержание

Правила игры

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

Семинарист: Симагин Денис, simagin.mail@yandex.ru

Ассистент: Владимир Гончаров, dev.zelta@gmail.com

Старайтесь не опаздывать на семинары, иначе вы можете прослушать важные анонсы, которые обычно будут проходить в начале занятий. А также пропустите много полезного. Приходите, будет интересно!

День недели Время проведения Аудитория
Вторник
09:00 – 10:20
327
Четверг
09:00 – 10:20
505

Структура курса

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

Домашние задания

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

Если я хочу прислать решение по 1-му домашнему заданию, а меня зовут Симагин Денис, то тема письма должна выглядеть так:

   H1 - Симагин Денис.

Семинары

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

Упражнения стоит присылать на почту семинаристу, при этом тема письма должна строго удовлетворять формату. К примеру, меня зовут Симагин Денис и я хочу отправить задачу с первого семинара, тогда заголовок письма должен иметь вид

   A01.21: Разворот списка - Симагин Денис.

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

Формула оценки

Оценка за семинары вычисляется следующим образом

   OСеминар = Сн·N/Nmax,
   N – количество набранных плюсов,
   Nmax – максимальное количество плюсов,
   Сн – нормирующий коэффициент (будет объявлен в конце семестра).

Оценка за домашние работы вычисляется как среднее за все 5 сданных работ. За работу в течении семестра студент получает накопленную оценку

   OНакопленная =  0.2·ОКонтрольная + 0.6·ОДомашние задания + 0.2·ОСеминары.

Итоговая оценка складывается из накопленной оценки и экзамена

   OИтоговая =  0.3·ОЭкзамена + 0.7·ОНакопленная.

Домашние задания

Задание H1

  1. Первая часть (16 февраля, 9:00)
  2. Вторая часть (16 февраля, 9:00)
  3. Контест (20 февраля, 20:00), решение.

Распределение задач здесь.

Задание H2

  1. Контест на динамику, дедлайн (2 марта, 20:00), решение.
  2. Контест на графы, дедлайн (14 марта, 20:00).

Распределение задач можно найти здесь.

Задание H3

  1. Контест на кратчайшии пути, дедлайн (3 апреля, 20:00), [решение].
  2. Контест на хеширование, дедлайн (26 апреля, 20:00), [решение].

Распределение задач можно найти здесь.

Задание H4

  1. Контест сборная солянка (22 мая, 23:59), [решение].

Распределение задач можно найти здесь.

Задание H5

  1. Листочек с теорией на конечные автоматы и регулярные языки (4 июня, 23:59), [решение].

Распределение задач можно найти здесь.

Семинары

Семинар A05.10

Оперативно разбирали темы, необходимые для домашней работы.

  1. Поговорили о жадном алгоритме декодирования префиксного кодирования. Для этого вам может потребоваться бор. Кстати, классическим примером префиксного кодирования является код Хаффмана.
  2. Поговорили о системе непересекающихся множеств. На семинаре была дана только верхняя оценка работы.
  3. Повторили двоичные кучи.

Семинар A04.26

Сегодня был только один человек на семинаре, да и то с большим опозданием.

Рассмотренные вопросы

  1. Дерево отрезков.
  2. Кратко о исключениях и как их бросать.
  3. Когда и почему инвалидируются итераторы.
  4. Что значит спецификатор const для методов функций.

максимальный по сумме подмассив (упражнение, 10 мая)

Дан массив целых чисел (положительных и отрицательных). Предложите структуру, позволяющую находить максимальный по сумме подмассив внутри указанной части исходного массива. Сложность O(log N), где N - размер массива.

[Описание алгоритма]


Re: Адаптируйте дерво отрезков для этих целей.

Ближайший общий предок (упражнение, 10 мая)

Дано бинарное дерево поиска. Предложите структуру, которая за O(log N) действий позволяет найти ближайшего общего предка для двух узлов. N - количество узлов в дереве.

[Описание алгоритма]


Re: Попробуйте предобработать дерево, построив дерево отрезков во время обхода (сложность O(n)).

Семинар A04.21

Продолжили разговор о деревьях поиска.

Рассмотренные вопросы

  1. Сравнение деревьев бинарного поиска и хешей (краткий ответ можно найти здесь).
  2. Обходы деревьев (почитать можно здесь).
  3. Оценка сложности работы деревьев.

Ссылки для дополнительного чтения

  1. АВЛ-дерево.
  2. Расширяющееся дерево (описаны только в 2м издании Кормена).
  3. B-дерево (хорошо описаны в Кормене).
  4. Случайные деревья (тема раскрыта в Кормене).


Семинар A04.19

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

Какие операции надо знать

  1. Вставка, удаление.
  2. Поиск по ключу
  3. Поиск минимального/максимального ключа.
  4. Поиск предыдущего/последующего ключа.

Ссылки для чтения

  1. Return value optimization.
  2. Умные указатели: unique, shared и weak.

Семинар A04.14

Занятия не было.

Семинар A03.14

Занятия не было.

Программа для робота

Наш робот стоит в клетке A квадратного поля. На каких-то клетка стоят ящики и поэтому робот не может на них встать. Напишите для робота программу, которая строила бы оптимальный путь до каждой доступной клетки.


Re: Используйте поиск в ширину.

Компоненты связаности

Предложите алгоритм, который подсчитывает число компонент связаности. А как вывести номера вершин для каждой компоненты?


Re: Используйте поиск в глубину.

Задачка от Смбата

Есть некоторый граф и указаны две вершины A и B. Предложите алгоритм, который выводит все ребра, через которые проходит хотя бы один оптимальный путь из A в В. Граф не ориентированный.


Re: Используйте поиск в ширину.


Двудольный граф

Проверить, является ли предложенный граф двудольным.

Re: Используйте поиск в ширину.

Диаметр (упражнение, 15 марта, 9:00)

Предложите алгоритм, находящий диаметр неориентированного графа.

Предок (упражнение, 15 марта, 9:00)

Дано бинарное дерево поиска. Предложите алгоритм, который за O(1) позволяет ответить, является ли вершина A предком для вершины B.

Re: На предобработку дерева допускается использовать O(|E| + |V|).


Семинар A03.03

Хранение графов (Упражнения)

  1. Граф хранится в виде списков смежности. Сколько нужно действий, чтобы узнать количество исходящих ребер из вершины? А входящих?
  2. Что произойдет с матрицей смежности ориентированного графа, если обратить все ребра. Как обратить ребра, если используется список смежности? Какое количество операций требуется?
  3. Покажите, что O(|V|) с помощью матрицы смежности можно обнаружить вершину, из которой не исходит ни одного ребра, но при этом есть ребра из все оставшихся вершин в нее.

Семинар A03.01

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

Семинар A02.25

  1. Провели защиту решений из контеста H1, примеры реализации можно посмотреть здесь.
  2. Поговорили о типах динамики.

Семинар A02.18

Разобрали теоретическую часть H1.

Максимальная неунывающая подпоследовательность

Дан массив целых чисел. Помогите неунывающей студентке Ане найти длину максимальной неубывающей подпоследовательности. К примеру, для набора [1 2 3 1 4] это будет [1 2 3 4], а для [0 2 0 2 0 2] есть несколько вариантов [0 0 0 2], [0 0 2 2], [ 0 2 2 2]. Вам же нужно вывести только длину.

[Описание алгоритма]

Задача о порядке перемножения матриц

Дана последовательность матриц, которую нужно перемножить, A · B · ... · C. Требуется минимизировать количество скалярных операций для вычисления их произведения. Матрицы предполагаются совместимыми по отношению к матричному умножению.

[Описание алгоритма]

Задача о монетках (Упражнение, 1 марта, 9:00)

Вам предлагается решить познакомиться с ресурсом hackerrank и решить следующую задачу.

[Решение]

Семинар A02.16

Разобрали теоретическую часть H1.

Семинар A02.11

Рассмотрели следующие темы:

  1. Алгоритм нахождения k-й статистики за O(n) в среднем.
  2. Алгоритм нахождения k-й статистики с гарантированной сложностью O(n).
  3. Алгоритм нахождения двух ближайших точек на плоскости за O(n log n).

Медианы и квантили

В математической статистике часто необходимо вычислить медиану для случайной величины или квантиль. Для этого удобно применять k-статистики. В частности для n реализаций некоторой случайной величины для фиксированного p можно найти x, что P[X < x] = p, как значение [pn] статистики.

Треугольник с минимальным периметром

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


Re: Задача поиска пары ближайших точек может быть сведена к задаче о треугольнике с минимальным периметром. Подробное решение можно найти здесь.

Минимальная сумма

Вам задан набор из n векторов на плоскости. Для каждого вектора разрешается домножить любые его координаты на -1. Вам нужно найти два вектора из набора и определить, какие из их координат следует умножить на -1 таким образом, чтобы модуль суммы полученных векторов был минимально возможным. Более подробное условие можно найти здесь.


Re: Минимальная сумма для произвольных двух векторов (x1, y1) и (x2, y2) может быть получена следующим образом (|x1| - |x2|, |y1| - |y2|). А дальше задача сводится к поиска ближайших двух точек.

n-th element (упражнение, 25 февраля)

Реализуйте линейный алгоритм нахождения n-й статистики.

[Решение]

Re: Допускается реализация алгоритма работающего за O(n) в среднем. В стандартной библиотеке есть схожий алгоритм. Изучите следующий материал.

3 vs 7 (упражнение*, 25 февраля)

Можно ли в алгоритме, находящем, n-й элемент с гарантированной линейной сложность вместо 5-ок объектов использовать 3-ки? А 7-ки? Ответ обоснуйте.

[Решение]

Re: Для решения воспользуйтесь доказательством сложности алгоритма из книги Кормана.

Ближайшие точки (упражнение, 25 февраля)

Реализуйте алгоритм нахождения двух ближайших точек на плоскости.

[Решение]

Re: Изучите следующий материал.

Семинар A02.04

Рассмотрели следующие методы решения рекуррентных соотношений:

  1. Индукция
  2. Раскрытие суммы
  3. Рекурсивное дерево
  4. Основная теорема.

Binary search (упражнение, 11 февраля)

В качестве тренировки предлагаю вам для бинарного поиска проделать все то же самое, что мы делали на семинаре для merge sort:

  1. Получить рекуррентную зависимость и применить основную теорему.
  2. Доказать оценку по индукции
  3. Раскрыть через сумму
  4. Доказать через дерево рекурсии.
[Решение]

Семинар A02.02

  1. Провели контрольную работу, разбор можно найти здесь.
  2. Порешали задачи на рекуррентные зависимости.

Семинар A01.28

  1. Поговорили о том, что значит оценки сложности в жизни.
  2. Разобрали сортировку подсчетом и разрядную сортировку.
  3. Начали осваивать рекуррентные соотношения.

Radix sort (упражнение, 4 февраля)

Реализуйте поразрядную сортировку для 64-битных чисел, один разряд -- это один байт (для этого вам придется реализовать сортировку подсчетом).

[Решение]

Re: Реализация только сортировки подсчетом стоит 1 балл.

Семинар A01.26

  1. Немного поговорили о задаче внешней сортировки.
  2. Разобрали упражнения на о-нотацию.
  3. Посмотрели примеры использования сортировок.

Равные массивы

Дано два массива чисел размера n, определить, являются ли эти массивы одинаковыми с точностью до перестановки элементов.

Re: Отсортируем массивы, теперь для проверки достаточно пройтись параллельно по обоим массивам, проверяя, что соответствующие элементы совпадают. Сложность алгоритма n log n. Эта идея используется, к примеру, здесь.

Уникальные элементы

Дан массив чисел длины n, как проверить, что все ли элементы в массиве уникальны?

Re: Отсортируем массив, теперь для проверки достаточно пройтись по массиву, проверяя, равны ли соседние элементы. Сложность алгоритма n log n. Эта идея используется, к примеру, здесь.

Разбиение на пары

Дан массив чисел размера 2n, как определить, можно ли разбить массив чисел на пары, которые дают сумму 1997.

Re: Отсортируем массив, теперь достаточно проверить, что для всех k < n выполняется a[k] + a[2n - k - 1] = 1997. Сложность алгоримат n log n.

Площадь наложения

На числовой прямой окрасили n отрезков. Известны координаты левого и правого концов каждого отрезка (целые числа). Найти длину окрашенной части числовой прямой.

Re: Отсортируем концы отрезков (2n штука) по координатам, если координаты совпадают, то левый конец больше правого. Теперь за одни проход концов можно вычислить закрашенную площадь. Для этого достаточно завести счетчик, указывающий количество отрезков, накрывающих следующий сегмент, и поддерживать его состояние. Сложность алгоримат n log n.

Задачи на О-нотацию (упражнение, 2 февраля)

Листочек с упражнениями можно найти здесь, на семинаре (A01.28) можно будет задавать по нему вопросы.

[Решение]

Семинар A01.21

  1. Закончили разбор сортировки in-place merge
  2. Поговорили о quick sort, особое внимание уделили выбору опорного элемента.
  3. Начали говорить о О-символике

В чем разница между O(f) и o(f)

Материал доступен здесь.

Quick sort (упражнение, 28 января)

Реализуйте сортировку qiuck sort.

[Решение]

Re: В качестве решения приведена комбинация quick sort и insertion sort. Замеры производительности можно посмотреть здесь.

Семинар A01.19

  1. Insert sort
  2. Merge sort
  3. in-place merge sort

Insertion sort

Реализуйте сортировку вставками.

[Решение Смбата]

External sorting (упражнение, 26 января)

У студента Никиты есть компьютер, оперативная память которого может хранить M чисел и имеет небольшой буфер. На диске у этого компьютера хранится массив размером 100M чисел и имеется еще куча свободного места. Предложите Никите алгоритм, с помощью которого он мог бы отсортировать свой массив.

[Решение]

Re: Подумайте, какие известные сортировки вы можете применить.

Merge sort (упражнение, 28 января)

Реализуйте сортировку слиянием.

[Решение]

Re: Для зачета вы должны пройти все тесты в контесте. За задачу вы получите два плюсика, реализовав функцию merge и функцию merge_sort. Код семинаристу стоит присылать только после того, как пройдены все тесты. Сначала присылайте первую задача, а затем уже саму сортировку.

In-place merge sort (упражнение, 28 января)

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

[Решение Никиты]

Re: Задача стоит 2 плюсика.

Семинар A01.14

  1. Множественная и одиночная рекурсии.
  2. Стек и куча.
  3. Мемоизация.
  4. Хвостовая рекурсия.
  5. Особенности реализации рекурсий.
  6. Принцип разделяй и властвуй.
  7. Бинарный поиск.

01 строки

Предложить рекурсивный алгоритм, выводящий всевозможные строки длины n из 0 и 1 в лексикографическом порядке.

[Решение]

Re: В решении продемонстрированы все основные особенности реализации рекурсивных функций.

Бинарный поиск

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

[Решение]

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

Ханойская башня - 1

Предложить рекурсивную функцию, печатающую последовательность перемещений (в формате (x, y), где x и y — номера стержней, с которого и на который перемещается диск), являющуюся решением задачи о Ханойской башне.

[Решение Свята]

Алгоритм Евклида (упражнение)

Реализовать рекурсивную версию алгоритма Евклида для нахождения наибольшего общего делителя.

[Решение Никиты]

Re: При правильном решении вы должны получить хвостовую рекурсию.

Ханойская башня - 2 (упражнение)

Реализовать рекурсивную функцию, получающую на вход число дисков Ханойской башни и выводящую состояние башень после каждого перемещения в оптимальном решении. Пример, n = 3, все диски на первом стержне:

  1. [3, 2, 1]
  2. []
  3. []

Состояние после перемещения верхнего диска на 3 стержень:

  1. [3, 2]
  2. []
  3. [1]

[Решение Святослава] [Решение]


Re: Для решения используйте задачу разобранную на семинре. Стержни можно смоделировать с помощью вектора.

Семинар A01.12

  1. Знакомство с группой.
  2. Рассмотрение примеров использования рекурсии.

Факториал

Предложить рекурсивный вариант вычисления факториала.

[Решение]

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

Фибоначчи

Предложить рекурсивный вариант вычисления чисел Фибоначчи.

[Решение]

Re: Показан пример сведения множественной рекурсии к одиночной.

Степень

Предложить рекурсивный алгоритм вычисления неотрицательной степени числа.

[Решение]

Разворот списка (упражнение)

Реализовать рекурсивную функцию reverse, которая обращает связи односвязанного списка в противоположную сторону. Таким образом последний элемент списка становится первым, предпоследний вторым, и т.д. Пусть список имеет вид [1, 2, 3, 4, 5], тогда после применения функции reverse он должен выглядеть, как [5, 4, 3, 2, 1].


Re: Кстати, кроме рекурсивных функций принято еще выделять и рекурсивные структуры данных, к примеру списки и деревья.
[Решение]