Модуль: ЕГЭ-2022. Вопрос 27. Обработка последовательности чисел


Задача

9 /11


Модифицированное демо - 2022

Теория Нажмите, чтобы прочитать/скрыть


Разбор задачи демо-варианта 2022 года


Немного исправим условие задачи, сделаем ее более универсальной. 

Задача
Дана последовательность из N натуральных чисел. Рассматриваются все её непрерывные подпоследовательности, такие что сумма элементов каждой из них кратна K. Найдите среди них подпоследовательность с максимальной суммой, определите её длину. Если таких подпоследовательностей найдено несколько, в ответе укажите количество элементов самой короткой из них.


Прежде чем разобраться в алгоритме решения данной задачи, необходимо вспомнить некоторые моменты из теории чисел. А именно, деление с остатком.
Любое число (a) представимо в виде: a = c * k + r, где c  - результат целочисленного деления числа a на k, r - остаток от деления a на k. Если число  a делится на k, то r = 0

Допустим, что сумма (s1)  некторых чисел не кратна k. Запишем ее в виде s1 = c1 * k + r1. Какое число из данной суммы надо убрать, чтобы сумма оставшихся чисел делилась на k?
Представим число, которое будем убирать в виде a = c * k + r.
Запишем разницу:
s2 = s1 - a  =  c1 * k + r1 -  (c * k + r) = k * (c1 - c) + (r1 - r)
s2 = k * (c1 - c) + (r1 - r) - результат данного выражения будет делиться на k в том случае, если r1-r=0. Следовательно, r1=r. Другими словами, сумма s1 и число a должны иметь один и тот же остаток при делении на k

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

Сумма элементов будет минимальной, если в ней меньше всего элементов (т.к. в последовательности только натуральные числа), максимальной - если в ней больше всего элементов.
 
Алгоритм 
1) При каждом новом считанном числе, увеличиваем сумму всех элементов последовательности (s). Также необходимо посчитать, какой остаток от деления на k будет иметь данная сумма: r = s % k.

Для того, чтобы сумма s делилась на k необходимо из нее убрать сумму элементов собственного префикса, которая имеет тот же остаток при делении на k, что и s.
2) Если такого префикса нет, значит при считывании числа, мы  получили данный префикс, и нужную последовательность определить не можем.  Сохраним сумму данного префикса в массиве (prefix[r]), его длину в другом массиве (mn_size). Длина префикса равна номеру считанного числа (при счете с 1): mn_size[r] = i + 1
3) Если же такой префикс есть в массиве, то можем вычислить сумму искомой последовательности, как s - prefix[s % k]. Длина такой последовательности будет равна i - mn_size[n % k]
4) При вычислении искомой суммы, ее необходимо проверять на максимальное значение и, в случае равенства с максимальным значением, проверять длину, чтобы в результате она оказалась минимальной.

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


 

Задача

Дана последовательность из N натуральных чисел. Рассматриваются все её непрерывные подпоследовательности, такие что сумма элементов каждой из них кратна K. Найдите среди них подпоследовательность с максимальной суммой, определите её длину. Если таких подпоследовательностей найдено несколько, в ответе укажите количество элементов самой короткой из них.

Входные данные
В первой строке записаны натуральные числа N (1 <= N <= 108) и K (1 <= K <= 100 ). Каждая из следующих N строк содержит одно натуральное число, не превышающих 10000.

Выходные данные
Выведите на экран одно число - количество элементов самой короткой подпоследовательности с максимальной суммой элементов кратной К.
 
 
Примеры
Входные данные Выходные данные
1 7 43
21
13
9
19
17
26
95
2

В этом наборе можно выбрать последовательности 21+13+9 (сумма 43) и 17+26 (сумма 43). Самая короткая из них, 17 + 26, имеет длину 2. Для указанных программа должна вывести число 2.

time 2000 ms
memory 256 Mb
Правила оформления программ и список ошибок при автоматической проверке задач

Статистика успешных решений по компиляторам
 Кол-во
С++ Mingw-w645
Python26
Комментарий учителя