ФИПИ · ЕГЭ · все форматы ответа · 2475 заданий
Тип задачи: Эффективная обработка данных и кластеры.
Учебные темы: Оценка сложности вычислений. Время работы и объём используемой памяти, их зависимость от размера исходных данных. Оценка асимптотической сложности алгоритмов. Алгоритмы полиномиальной сложности. Переборные алгоритмы. Примеры различных алгоритмов решения одной задачи, которые имеют различную сложность; Массивы и последовательности чисел. Вычисление обобщённых характеристик элементов массива или числовой последовательности (суммы, произведения, среднего арифметического, минимального и максимального элементов, количества элементов, удовлетворяющих заданному условию). Линейный поиск заданного значения в массиве. Алгоритмы работы с элементами массива с однократным просмотром массива. Сортировка одномерного массива. Простые методы сортировки (метод пузырька, метод выбора, сортировка вставками). Сортировка слиянием. Быстрая сортировка массива (алгоритм QuickSort). Двоичный поиск в отсортированном массиве.
| КЭС: | 3.2 Оценка сложности вычислений. Время работы и объём используемой памяти, их зависимость от размера исходных данных. Оценка асимптотической сложности алгоритмов. Алгоритмы полиномиальной сложности. Переборные алгоритмы. Примеры различных алгоритмов решения одной задачи, которые имеют различную сложность 3.3 Определение возможных результатов работы простейших алгоритмов управления исполнителями и вычислительных алгоритмов. Определение исходных данных, при которых алгоритм может дать требуемый результат 3.4 Алгоритмы обработки натуральных чисел, записанных в позиционных системах счисления: разбиение записи числа на отдельные цифры, нахождение суммы и произведения цифр, нахождение максимальной (минимальной) цифры. Представление числа в виде набора простых сомножителей. Алгоритм быстрого возведения в степень. Поиск простых чисел в заданном диапазоне с помощью алгоритма «решето Эратосфена» 3.5 Многоразрядные целые числа, задачи длинной арифметики |
| Тип ответа: | Краткий ответ |
Ответ: 471228 49113954961677
Решение.
Соседние контейнеры расположены через 3 км. Груз из каждого контейнера доставляется к выбранному центру по кратчайшему из двух направлений кольца. Обозначим количества мусора через a₀, a₁, …, aₙ₋₁, а центр — индексом k, считая индексы с нуля.
Сначала считаем расстояния в промежутках между соседними контейнерами. Для контейнера i это min(|i − k|, N − |i − k|). Стоимость Cₖ в таких единицах равна сумме произведений aᵢ на эти расстояния. Полученный минимум умножим на 3, чтобы учесть километры.
Прямой пересчёт суммы для каждого центра занял бы O(N²) времени. Вместо этого вычислим C₀ одним проходом, а затем будем переносить центр на соседний контейнер, обновляя сумму за постоянное время.
Пусть S — общее количество мусора, m — целая часть половины N. Обозначим через Fₖ сумму мусора в следующих m контейнерах по направлению движения от центра k. Все индексы при выходе за N − 1 циклически возвращаются к началу.
При чётном N расстояния до этих m контейнеров уменьшаются на один промежуток, а до остальных увеличиваются на один. Поэтому новая стоимость получается из старой так:
Cₖ₊₁ = Cₖ + (S − Fₖ) − Fₖ = Cₖ + S − 2Fₖ.
При нечётном N контейнер с индексом k + m + 1 находится на одинаковом расстоянии m от старого и нового центров. Его вклад не меняется. Его массу aₖ₊ₘ₊₁ нужно исключить из группы, расстояния до которой увеличиваются:
Cₖ₊₁ = Cₖ + S − 2Fₖ − aₖ₊ₘ₊₁.
Сама сумма F обновляется удалением ближайшего контейнера и добавлением следующего дальнего:
Fₖ₊₁ = Fₖ − aₖ₊₁ + aₖ₊ₘ₊₁.
Таким образом, после начального прохода посещаем все N возможных центров и выбираем минимальную стоимость. Формулы учитывают и чётное, и нечётное количество контейнеров; при N = 1 перевозка не нужна и стоимость равна нулю.
Скачиваемый ZIP объединяет два исходных файла A и B официального варианта ФИПИ. Содержимое этих TXT сохранено без изменений.
Программа на Python 3. Оба файла из архива сохраняем под указанными в программе именами:
def minimum_cost(filename):
with open(filename, encoding='utf-8-sig') as source:
n, *weights = map(int, source.read().split())
assert len(weights) == n
half, odd = divmod(n, 2)
total = sum(weights)
cost = sum(weight * min(index, n - index)
for index, weight in enumerate(weights))
forward = sum(weights[1:half + 1])
best = cost
for center in range(n - 1):
opposite = weights[(center + half + 1) % n]
cost += total - 2 * forward
if odd:
cost -= opposite
forward += opposite - weights[(center + 1) % n]
best = min(best, cost)
return 3 * best
print(minimum_cost('107_27_A.txt'),
minimum_cost('107_27_B.txt'))Результаты для исходных данных:
| Показатель | Файл A | Файл B |
|---|---|---|
| Количество контейнеров | 130 | 1200030 |
| Общее количество мусора | 5034 | 54586979 |
| Номер оптимального контейнера, считая с единицы | 25 | 206940 |
| Минимальная стоимость с расстояниями в км | 471228 | 49113954961677 |
Проверка выполнена прямым суммированием расстояний от каждого контейнера до найденного центра: получаются те же значения. Независимый способ через накопленные суммы масс и произведений масс на индексы подтвердил стоимость для каждого возможного центра, а не только итоговый минимум.
Числа в иллюстративном примере условия расположены через 1 км; при работе с основными файлами используем именно 3 км. Это объясняет множитель 3 в последней строке функции.
Время работы O(N), память O(N). Python хранит целые числа точно; все вычисления здесь выполняются без округления.
Ответ: 471228 49113954961677.
Напишите пожелание к сайту или решению либо сообщите о найденной неточности в задании EGEINFBED6E1.
Сообщение увидит только команда сайта: на странице оно не публикуется.
Комментарии к решению
Комментарии видны всем посетителям сайта.
Комментариев пока нет. Будьте первым.
Чтобы оставить комментарий, войдите или зарегистрируйтесь.