Глазурь
Кондитер украшает огромный торт, покрывая прямоугольную поверхность разноцветной глазурью. Для приготовления глазури он смешивает сахарную пудру с лимонным и черничным соком в разных пропорциях, чтобы получить три оттенка синего цвета: светлый, средний и насыщенный. Эти цвета обозначаются числами: 0 для светлого, 1 для среднего и 2 для насыщенного синего.
Чтобы получить красивый узор, он разделяет поверхность торта на вертикальные полосы шириной A1, A2, ..., An сантиметров и горизонтальные полосы высоты B1, B2, ..., Bn сантиметров. В результате полосы делят поверхность торта на n × n прямоугольников. Пересечение вертикальной полосы i и горизонтальной полосы j имеет цветовой номер (i + j) mod 3 для всех 1 ≤ i, j ≤ n:
Помогите кондитеру определить площадь каждого из трех цветов в квадратных сантиметрах. Программа получает на вход целое положительное число n, и две строки, в которых перечисляется ширина и высота полос.
Пример ввода
Вывод
Решение
Наша цель – найти решение, которое работает за время O(n) или O(n log n) в худшем случае. Первое, что приходит в голову – перебрать все ячейки сетки n x n и посчитать площадь каждого цвета отдельно. Однако это решение займет слишком много времени, так как количество операций растет пропорционально квадрату n.
Более оптимальный подход
Если мы поменяем столбцы или строки местами, то общая площадь каждого цвета останется прежней. Например, если мы переместим столбец целиком, то темно-синие ячейки просто переместятся вместе со столбцом, не изменяя их общей площади.
Следовательно, достаточно рассмотреть случай n = 3. Тогда мы можем просто посчитать площади каждого цвета, суммируя ячейки с одинаковым остатком от деления суммы индексов строки i и столбца j на 3. Например:
- A3k (светло-синий): сумма площадей ячеек, где (i + j) дает остаток 0 при делении на 3
- A3k+1 (средний синий): сумма площадей ячеек, где (i + j) дает остаток 1 при делении на 3
- A3k+2 (насыщенный синий): сумма площадей ячеек, где (i + j) дает остаток 2 при делении на 3
Таким образом, мы можем найти площадь каждого цвета, просмотрев только сетку 3 x 3. Единственная сложность – нужно правильно учитывать цвета при суммировании площадей:
Учитесь программировать на Python в удобном темпе!
Вы хотите начать карьеру в IT или повысить свои навыки программирования? Наш курс идеально подходит как для новичков, так и для начинающих разработчиков!
💡 Что вас ждет на курсе
- 32 урока практических занятий.
- 4 проекта для личного портфолио: бот для Telegram, парсинг веб-страниц, генератор безопасных паролей, калькулятор для ипотеки.
- 90 часов практики и 15 часов теории.
- Работа в PyCharm и Jupyter Notebook.
- Обратная связь от опытных преподавателей.
👨🏫 Преподаватели
- Роман Булгаков — эксперт с 5-летним стажем, готовит школьников и студентов к олимпиадам по информатике.
- Артур Сапрыкин — Ex-Data Scientist ПАО «Мегафон», работал с крупными проектами по обработке естественного языка и анализом аудио.
📅 Начало курса в любое время! Учитесь в удобном для вас темпе на платформе CoreApp.
Вид на море
При застройке набережной строительная компания расположила здания в неправильном порядке. В результате многие дома не имеют вида на море:
Власти города решили снести все здания, перекрывающие вид на море. Напишите программу, которая получает на вход список, в котором перечисляется количество этажей каждого здания, и возвращает список зданий, которые останутся после сноса.
Пример ввода
Вывод
Решение
Задача сводится к поиску наибольшей увеличивающейся подпоследовательности. Сложность этого алгоритма составляет O(n log m), где n – размер входного массива x, а m – размер самой длинной возрастающей подпоследовательности.
Основные идеи решения:
- Для каждого индекса i мы добавляем элемент x_i к самой длинной возрастающей подпоследовательности, которая строится на основе префикса x_1, ..., x_{i-1}.
- Чтобы найти оптимальное решение, мы будем рассматривать множество всех возможных подпоследовательностей префикса x_1, ..., x_{i-1}. Две важных характеристики каждой подпоследовательности y – это ее длина и последний элемент.
- Мы будем хранить только недоминируемые подпоследовательности, то есть те, которые не меньше по длине и не больше по последнему элементу, чем другие подпоследовательности той же длины. Это позволит нам избежать хранения избыточной информации.
- Для эффективного хранения недоминируемых подпоследовательностей мы будем использовать массив b, где b[k] – последний элемент самой длинной подпоследовательности длины k. Этот массив будет строго возрастающим.
- Когда мы рассматриваем очередной элемент x_i, то ищем, в какую из недоминируемых подпоследовательностей можно добавить x_i, чтобы получить новую, более длинную подпоследовательность. Это можно сделать за O(log m) с помощью бинарного поиска.
- Для хранения самих подпоследовательностей мы используем связанные списки, представленные с помощью двух массивов: h (хранит индексы элементов в x) и p (хранит индексы предыдущих элементов в списке).
Цукаты
Вася очень любит цукаты, но терпеть не может пироги. Однако цукаты можно получить только вместе с куском пирога, который они украшают. Какой наименьший кусок пирога должен отрезать Вася, чтобы получить хотя бы одному из всех видов цукатов?
Цукаты обозначаются буквами английского алфавита. Программа сначала получает строку с буквами, а затем целое число – нужное количество разновидностей цукатов.
Пример ввода
Вывод
Решение
Это вариант популярной на собеседованиях задачи по подсчету элементов в каждом окне размера k. В нашем случае решение должно определять диапазон куска, в который входит хотя бы один экземпляр из заданного количества видов цукатов. Решение имеет временную сложность O(n), где n – длина входной строки, так как оно проходит по строке один раз, используя скользящее окно:
Спутниковые антенны
Бесконечная береговая линия определяется как ось x. Море находится выше оси x, а суша – ниже. В море расположены небольшие острова, которые можно считать точками с координатами x и y. Зеленые спутниковые антенны, расположенные на берегу, могут покрывать дистанцию d. Необходимо написать программу, которая в первой строке получает дистанцию d и число островов n, а во второй – n наборов координат островов, и определяет минимальное необходимое количество антенн для покрытия всех островов:
Пример ввода
Вывод
Решение
Воспользуемся подходом, который лежит в основе алгоритма заметающей прямой. Основная идея состоит в том, чтобы проходить линию от левого края до правого по плоскости, обрабатывая события, которые происходят при пересечении этой линии с объектами на плоскости. Сложность решения составляет O(n log n):
Самый длинный палиндром
Напишите программу, которая получает на вход строку, содержащую один или более палиндромов, и определяющую самый длинный из них. Если в строке содержатся несколько палиндромов одинаковой длины – вывести любой из них. Пробелов и знаков препинания в строке нет.
Пример ввода
Вывод
Решение
Эту задачу можно решить за квадратичное время с наивным алгоритмом и за O(n log n) с помощью массивов суффиксов. Более эффективный подход предлагает алгоритм Манакера, разработанный в 1975 году.
Ключевая идея алгоритма – использовать симметрию палиндромов, чтобы эффективно вычислять длины максимальных палиндромов, центрированных на каждом символе входной строки.
Предположим, что есть палиндром, центрированный на c, радиуса d – c, где d – максимальный такой индекс. Пусть j – зеркальное отражение i относительно c.
Из симметрии следует, что палиндром, центрированный на j, радиуса p[j], должен быть равен слову, центрированному на i, по крайней мере, до радиуса d – i. Следовательно, p[j] является нижней границей для значения p[i].
Это значит, что мы можем начать вычисление p[i] с p[j] и двигаться вправо, сравнивая символы, пока они совпадают. Это позволяет вычислить p[i] за линейное время, так как мы используем информацию, полученную при вычислении предыдущих значений p:
Основные этапы решения:
- Преобразуем входную строку s, вставляя разделитель # вокруг каждого символа и добавляя ограничители ^ и $ по краям строки. Например, abc преобразуется в ^#a#b#c#$. Пусть полученная строка называется t.
- Это позволяет обрабатывать одинаковым образом палиндромы как четной, так и нечетной длины.
- Заметим, что при этом преобразовании каждый палиндром начинается и заканчивается с разделителя #. Таким образом, два конца палиндрома имеют индексы с одной и той же четностью, что упрощает преобразование решения для строки t в решение для исходной строки s.
- Ограничители ^ и $ избавляют от необходимости рассматривать граничные случаи.
Другие задачи
Решаем 5 олимпиадных задач на Python: используем битовую маску для выбора симпатичных узоров, находим оптимальную стратегию игры, подсчитываем варианты вырубки деревьев, и выясняем, за сколько секунд можно пробежать по эскалатору.
Подготовка к собеседованию по Python: составляем анонимку, проверяем гипотезу Коллатца, решаем судоку, разрабатываем кэш для операций над ISBN и вычисляем интервалы занятости.
Решаем 5 интересных задач: проверяем двоичные деревья на симметричность, вычисляем расстояние Дамерау-Левенштейна и оцениваем сложность алгоритмов.
Комментарии