Общий день двух расписаний

тема: Теория чисел (НОД, НОК, остатки) · уровень: базовый

Условие

В школе есть два события: одно повторяется каждые a дней, другое — каждые b дней. Сегодня оба события случились в один день.

Определи, через сколько дней они снова совпадут в один и тот же день.

Важно: искомое число может быть больше, чем помещается в 32-битный тип (как на олимпиадах), хотя входные числа небольшие.

Формат ввода

В одной строке записаны два целых числа a и b.

Формат вывода

Выведи одно целое число — через сколько дней события снова совпадут.

Ограничения

Пример

Ввод:

6 15

Вывод:

30

Как решать — идея подхода

Приём: НОК через НОД (алгоритм Евклида)

Ключевое наблюдение: событие с периодом a бывает в дни, кратные a (a, 2a, 3a, …), а с периодом b — в дни, кратные b. Значит, следующий общий день — это наименьшее число, которое делится и на a, и на b, то есть НОК(a, b).

Почему работает приём: напрямую перебирать дни долго, зато есть связь НОК и НОД: lcm(a, b) = a / gcd(a, b) * b. НОД (наибольший общий делитель) быстро находится алгоритмом Евклида за логарифмическое время.

План решения:

Сложность: O(log(min(a, b))) по времени и O(1) по памяти.

Частая ошибка: считать a * b // g. В Python это обычно безопасно, но в языках с фиксированными int можно получить переполнение. Правильнее делить раньше: (a // g) * b.

Разберись руками

Одно событие повторяется каждые 6 дней, другое — каждые 15 дней. Сегодня они совпали. Хочется найти первый следующий день, который делится и на 6, и на 15.

Идея: Совпадение будет в те дни, которые одновременно являются кратными обоих периодов. Нужно найти самое маленькое такое число (его называют «наименьшее общее кратное»): можно выписать кратные обоих периодов и взять первое общее.

Решить задачу с автопроверкой на Python →

Куда дальше