27.01 Передвижение по магистрали
Ошибка.
Попробуйте повторить позже
У медицинской компании есть N пунктов приёма биоматериалов на анализ. Все пункты расположены вдоль автомагистрали и имеют номера, соответствующие расстоянию от нулевой отметки до конкретного пункта. Известно количество пробирок, которое ежедневно принимают в каждом из пунктов.
Благодаря развитию нанотехнологий и изобретению телепортов компания, расположив в каждом пункте по одному устройству телепортации, может отправлять некоторое количество пробирок напрямую в лабораторию абсолютно бесплатно. Но так как телепортация - новая технология, пока что ещё запускать телепорты можно только раз в день, и перемещать они могут только число пробирок, являющееся членами последовательности Фибоначчи.
Поэтому компания решила телепортировать из каждого пункта максимально возможное число пробирок, а остальные поштучно доставлять в лабораторию по автомагистрали.
Стоимость перевозки биоматериалов равна произведению расстояния от пункта до лаборатории на количество пробирок. Общая стоимость перевозки за день равна сумме стоимостей перевозок из каждого пункта в лабораторию. Лабораторию расположили в одном из пунктов приёма биоматериалов таким образом, что общая стоимость доставки биоматериалов из всех пунктов минимальна.
Определите минимальную общую стоимость доставки биоматериалов из всех пунктов приёма в лабораторию.
Входные данные: Дано два входных файла (файл A и файл B), каждый из которых в первой строке содержит число – количество пунктов приёма биоматериалов. В каждой из следующих N строк находится два числа: номер пункта и количество пробирок в этом пункте (все числа натуральные, количество пробирок в каждом пункте не превышает 1000).
Пункты перечислены в порядке их расположения вдоль дороги, начиная от нулевой отметки.
В ответе укажите два числа через пробел: сначала значение искомой величины для файла A, затем – для файла B.
# Файлик A # Функция, которая вычитает максимальное подходящее число фибоначчи из числа пробирок def fib(x): mx = max([i for i in fibs if x >= i]) return x - mx # Сначала необходимо сгенерировать числа фибоначчи до 1000 fibs = [0, 1, 1] while fibs[-1] <= 1000: fibs.append(fibs[-2] + fibs[-1]) f = open(’4_27A.txt’) n = int(f.readline()) points = [] for i in f: dist, cnt = map(int, i.split()) # С поиощью нашей функции fib находим остаток нетелепортированных пробирок points.append([dist, fib(cnt)]) costs = [] for cur_d, cur_c in points: # Перебираем пункты, где можем поставить лабораторию sm = 0 for dist, cnt in points: # Для пункта увеличиваем сумму - умножаем расстояние до лаборатории на количество контейнеров sm += abs(dist - cur_d) * cnt costs.append(sm) print(min(costs)) # Файлик B # Функция, которая вычитает максимальное подходящее число фибоначчи из числа пробирок def fib(x): mx = max([i for i in fibs if x >= i]) return x - mx # Сначала необходимо сгенерировать числа фибоначчи до 1000 fibs = [0, 1, 1] while fibs[-1] <= 1000: fibs.append(fibs[-2] + fibs[-1]) f = open(’4_27B.txt’) n = int(f.readline()) # Список, в котором индекс - расстояние от нулевой отметки до этого пункта # элементы - количества контейнеров # Если на какой-то отметке пункта нет, там останется 0, и этот пункт не будет # влиять на сумму points = [0] * 10 ** 7 # Индексы первого и последнего реального пункта start = 10 ** 10 end = -1 for i in range(n): # Считываем номер пункта и количество пробирок num, cnt = map(int, f.readline().split()) # Вставляем на нужную отметку кол-во контейнеров # С поиощью нашей функции fib находим остаток нетелепортированных пробирок points[num] = fib(cnt) # Определяем крайние пункты if cnt > 0: start = min(start, num) end = max(end, num) # Удаляем нулевые пункты по краям points = points[start: end + 1] # Изначальная сумма для 0-го пункта sm = 0 for i in range(len(points)): # Умножаем кол-во контейнеров на расстояние до 0-го пункта sm += points[i] * i # Если мы смещаемся на пункт вправо - расстояние до всех пунктов слева увеличится на 1, # значит общая сумма увеличится на сумму пунктов слева # Расстояние до всех пунктов справа уменьшится на 1, # значит общая сумма уменьшится на сумму пунктов справа # Сумма слева, на которую увеличится общая сумма при перемещении на один пункт вправо left = 0 # Сумма справа, на которую уменьшится общая сумма при перемещении на один пункт вправо right = sum(points) current_cost = sm # Список сумм для каждого пункта costs = [sm] for i in range(1, len(points)): # При перемещении на 1 пункт вправо из правой суммы исчезает самый перый элемент, # а к левой этот элемент прибавляется left += points[i - 1] right -= points[i - 1] # Рассчёт новой суммы, после увеличения суммы левой суммой и уменьшения правой суммой current_cost = current_cost + left - right if points[i] > 0: costs.append(current_cost) print(min(costs))
Специальные программы
Программа
лояльности v2.0
Приглашай друзей в Школково и получай вознаграждение до 10%!
Крути рулетку
и выигрывай призы!
Крути рулетку и покупай курсы со скидкой, которая привязывается к вашему аккаунту.
Бесплатное онлайн-обучение
Для школьников из приграничных территорий России, проживающих в ДНР, ЛНР, Херсонской, Запорожской, Белгородской, Курской, Брянской областях и Крыму.
Налоговые вычеты
Узнай, как получить налоговый вычет при оплате обучения в «Школково».
Специальное предложение
для учителей
Бесплатный доступ к любому курсу подготовки к ЕГЭ, ОГЭ и олимпиадам от «Школково». Мы с вами делаем общее и важное дело, а потому для нас очень значимо быть чем-то полезными для учителей по всей России!
Вернём деньги за курс
за твою сотку на ЕГЭ
Сдать экзамен на сотку и получить обратно деньги за подготовку теперь вполне реально!