October 15, 2021

Задание 26

Источник: сайт К.Ю Полякова, 3755

Алгоритм решения:

  1. Прочесть файл
  2. Отсортировать товары по цене
  3. Закупить товар A
  4. Закупить товар Z

1. Прочесть файл:

s = open('26-42.txt')
n, suma = map(int, s.readline().split())

Открываем файл; читаем первую, разделяем её и преобразовываем

price = list([ [],[] ])
count = [0,0]

Создаём списки: price для хранения всех товаров, count для подсчёт купленых товаров. Соответсвенно, в 1ой ячейки листов будет храниться A товар, во 2ой ячейки будет храниться Z товар.

for _ in range(n):
    a, b, c = s.readline().split()
    b, c = int(b), int(c)
    if a == 'A':
        price[0].append([b,c])
    else:
        price[1].append([b,c])

for _ используется для того, чтобы не создавать временную переменную. Иными словам, повторить действие в цикле n раз.

Считываем строку, и разделяем её.

По заданию: a - тип товара, b - цена одного товара, наконец, c - количество товара.

Преобразовываем b и c в числовой тип. Можно писать линейно.

b = int(b)
c = int(c)

Если a - это A товар, то мы добавляем цену и количество как список. А если a - это Z товар, то добавляем во-вторую ячейку. У нас получается вложенный спсписок, в таких типах заданиях это очень удобно.

, в таких типах заданиях это очень удобно.

Пример вложенного листа: [ [[1, 2], [3, 4], [5, 6]], [[10, 11], [3, 4], [15, 5]] ]

2.Отсортировать товары, по-цене

for key in range(len(price)):
    price[key] = sorted(price[key], key=lambda x: x[0])

Мы идём по индексам листа с товарами (у нас 2 индекса всего, тк два товара).

Значение ячейки price[key] - цена и количество товара типа AZ - равна она сама, но отсортированная. Сортировка происходит с помощью ключа и лямба-функции, которая указывает функции sorted(), что сортируй по первому значению вложенного листа. Например, возьём вот такой вложенный лист.

[ [[1, 2], [3, 4], [5, 6]], [[10, 11], [3, 4], [15, 5]] ]        

Берём 1 ячейку циклом for: [[1, 2], [3, 4], [5, 6]]. key указывывает то, что нужно сортировать, по-первому, значению вложенного цикла. В данном случае мы "говорим" функции: отсортируй мне по значениям 1, 3, 5 списки. Она сортирует и возращает их, а мы привязываем их к текущему значению типа товара.

3.Закупить товар A

while len(price[0]) > 0:
    a, b = price[0].pop(0)
    while b > 0 and suma - a >= 0:
        count[0] += 1
        suma -= a
        b -= 1

Закупаем товар A пока он есть. a и b - цена одного товара и его количество. Закупаем конкретную партию пока товар есть в наличии, и пока у нас есть деньги. Увеличиваем количество купленного товара типа A. Уменьшаем наш бюджет. Уменьшаем количество товара в партии. То есть мы добавляем по-одному самому маленькому товару пока можем.

Тут важно понимать, что в задании указано то, что есть много вариантов закупки товаров, но ключевая фраза: "нужно выбрать вариант, при котором оставшаяся сумма максимальна". Это значит, что нам нельзя "добивать" самый дорогой товар в нашу общую закупку, в отличии от 26 задания на диски.

4.Закупить товар Z

while len(price[1]) > 0:
    a, b = price[1].pop(0)
    while b > 0 and suma - a >= 0:
        count[1] += 1
        suma -= a
        b -= 1

Код для закупки товара Z, абсолютно аналогичный, но только мы, соответственно, меняем индекс листа с [0] на [1].

print(price[1], suma)

Ответ: 6111 190

Полный код:

s = open(r'26-42.txt')
n, suma = map(int, s.readline().split())
price = list([ [],[] ])
count = [0,0]
for _ in range(n):
    a, b, c = s.readline().split()
    b, c = int(b), int(c)
    if a == 'A':
        price[0].append([b,c])
    else:
        price[1].append([b,c])
        
for key in range(len(price)):
    price[key] = sorted(price[key],key=lambda x: x[0])

while len(price[0]) > 0:
    a, b = price[0].pop(0)
    while b > 0 and suma - a >= 0:
        count[0] += 1
        suma -= a
        b -= 1
        
while len(price[1]) > 0:
    a, b = price[1].pop(0)
    while b > 0 and suma - a >= 0:
        count[1] += 1
        suma -= a
        b -= 1
        
print(count[1],suma)
Редактор: andy