Практикум: решение задач ЕГЭ №8 и алгоритмических задач с собеседований
Мы прошли долгий путь: от базовых правил суммы и произведения до сложных формул с повторениями и генераторов itertools. Теперь пришло время собрать все знания воедино и применить их на практике.
В этой финальной статье курса мы рассмотрим два мира:
Мир экзаменов (ЕГЭ по информатике), где комбинаторика встречается в задании №8. Мы научимся решать их двумя способами: аналитически (ручкой на бумаге) и программно (скриптом на Python).
Мир IT-собеседований, где комбинаторные задачи проверяют ваше умение оптимизировать перебор и видеть математическую структуру алгоритма.Часть 1. Комбинаторика в ЕГЭ (Задание №8)
Задание №8 в ЕГЭ по информатике проверяет умение подсчитывать количество вариантов построения символьных последовательностей. Раньше эти задачи решали только формулами, но с появлением компьютеров на экзамене Python стал «легальным чит-кодом».
Типовая задача: Слова с ограничениями
Условие:
Сколько существует 5-буквенных слов, составленных из букв слова «ПИТОН», в которых буква «О» встречается ровно один раз, а буква «Н» не стоит на первом месте? Каждая буква может использоваться несколько раз.
#### Способ 1: Аналитическое решение
Давайте рассуждать математически. У нас есть алфавит из 5 букв: П, И, Т, О, Н. Длина слова — 5 позиций.
Условие 1: Буква «О» встречается ровно 1 раз. Она может стоять на одной из 5 позиций.
Условие 2: Буква «Н» не может стоять на первом месте.Разобьем задачу на два случая в зависимости от того, где стоит буква «О».
Случай А: Буква «О» стоит на первом месте.
1-я позиция: занята «О» (1 вариант).
Остальные 4 позиции: могут быть заняты любыми буквами, кроме «О» (так как она только одна). Алфавит для них: {П, И, Т, Н}. Всего 4 буквы.
Ограничение на «Н» (не на первом месте) выполняется автоматически, так как там стоит «О».Количество вариантов для случая А:
Где — количество слов, начинающихся на «О», а — количество доступных букв для остальных позиций.
Случай Б: Буква «О» стоит НЕ на первом месте.
«О» может занимать 2-ю, 3-ю, 4-ю или 5-ю позицию (4 варианта расположения).
1-я позиция: не может быть «О» (она занята в другом месте) и не может быть «Н» (по условию). Доступны: {П, И, Т}. Всего 3 варианта.
Остальные 3 позиции: любые буквы, кроме «О». Доступны: {П, И, Т, Н}. Всего 4 варианта.Количество вариантов для случая Б:
Где — количество слов, где «О» не на первом месте, — выбор места для «О», — выбор первой буквы, — выбор остальных букв.
Итоговый ответ:
Где — общее количество искомых слов.
#### Способ 2: Программное решение (Python)
На экзамене легко ошибиться в арифметике. Python позволяет решить эту задачу методом грубой силы (brute force), перебрав все варианты. Для длины 5 и алфавита 5 это всего вариантов, что для компьютера — мгновение.
Мы будем использовать itertools.product, так как буквы могут повторяться (размещения с повторениями).
> Совет: Всегда используйте программный метод для проверки аналитического решения, если пространство перебора не превышает 10-20 миллионов вариантов.
Часть 2. Алгоритмические собеседования (FAANG)
На собеседованиях в Яндекс, Google или Amazon вам не дадут задачу «посчитать количество слов». Вас попросят написать алгоритм, который генерирует эти комбинации или использует комбинаторные свойства для оптимизации.
Задача 1: Генерация всех подмножеств (Subsets)
Условие (LeetCode 78):
Дан массив уникальных чисел nums. Вернуть все возможные подмножества (булеан).
Пример: [1, 2] [], [1], [2], [1, 2].
Анализ:
Количество подмножеств множества из элементов равно . Это классическая задача на сочетания. Нам нужно выбрать 0 элементов, потом 1 элемент, потом 2... и так до .
Решение через itertools:
Здесь идеально подходит функция combinations, запущенная в цикле по длине подмножества.
Сложность этого алгоритма — , так как мы генерируем объектов. Быстрее сделать невозможно, так как таков размер выходных данных.
Задача 2: Уникальные пути (Unique Paths)
Условие (LeetCode 62):
Робот находится в левом верхнем углу сетки . Он может двигаться только вниз или вправо. Сколькими способами он может добраться до правого нижнего угла?
!Робот в лабиринте выбирает путь только вправо и вниз
Решение методом динамического программирования:
Обычно эту задачу решают, создавая таблицу и суммируя пути. Сложность .
Решение методом комбинаторики:
Давайте посмотрим на задачу иначе. Чтобы дойти от старта до финиша в сетке , робот обязан сделать ровно шагов вниз и шагов вправо. Порядок шагов может быть любым, но их количество фиксировано.
Всего шагов:
Где — общая длина пути.
Нам нужно выбрать, на каких именно позициях из этих шагов робот пойдет «Вниз». Остальные шаги автоматически станут «Вправо».
То есть задача сводится к выбору позиций из доступных. Это формула сочетаний!
Где — число сочетаний, — факториал.
Решение на Python:
Это решение имеет сложность или даже , если считать арифметические операции за константу. Это намного эффективнее динамического программирования по памяти.
Задача 3: Следующая перестановка (Next Permutation)
Условие (LeetCode 31):
Реализовать алгоритм, который перестраивает числа в массиве так, чтобы получить следующую лексикографически (по алфавиту) большую перестановку. Если такой нет, вернуть минимальную (отсортированную).
Пример: [1, 2, 3] [1, 3, 2] [2, 1, 3].
Почему нельзя использовать itertools?
Если массив длинный (например, 100 элементов), генерация всех перестановок через itertools.permutations займет вечность ( — астрономическое число). Нам нужно найти только одну следующую.
Алгоритм:
Найти первый элемент с конца, который нарушает убывающий порядок (назовем его ).
Найти с конца элемент, который больше .
Поменять их местами.
Развернуть (reverse) часть массива после позиции .Это пример задачи, где знание того, как устроены перестановки, важнее, чем умение вызывать библиотечную функцию.
Когда использовать формулы, а когда перебор?
| Ситуация | Подход | Почему | Сложность |
| :--- | :--- | :--- | :--- |
| ЕГЭ №8 (малые числа) | itertools | Быстро пишется, исключает ошибки вычислений | Зависит от , обычно приемлемо |
| ЕГЭ №8 (огромные числа) | Формулы | Перебор вариантов не сработает по времени | |
| Собеседование (найти количество) | Формулы / DP | Требуется оптимальное решение | или |
| Собеседование (вывести все варианты) | Рекурсия / itertools | Нужно вернуть список объектов | или |
Заключение курса
Поздравляем! Вы прошли путь от основ правил суммы и произведения до решения задач уровня Google.
Комбинаторика — это не просто раздел математики про «доставание шаров из урны». Это язык, на котором мы говорим о сложности алгоритмов, о криптографии, о генерации тестов и о структуре данных.
Ваш чек-лист навыков:
[x] Понимаете разницу между и .
[x] Знаете, когда порядок важен, а когда нет.
[x] Умеете использовать itertools для генерации данных.
[x] Можете оценить, «взорвется» ли ваш алгоритм от факториальной сложности.Удачи на экзаменах и собеседованиях! Практикуйтесь, и формулы станут вашими верными инструментами.