Олимпиадная задача на программирование

Рейтинг: -1Ответов: 1Опубликовано: 20.01.2023

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

Как я понял мне необходимо его оптимизировать, но как еще можно это сделать(код ниже - это, примерно, 4 версия изначального) я не знаю.

Задача: Кондитерская фабрика города П, в котором живет Петя делает очень вкусные конфеты. Как-то раз, Петя собрался в гости к своему другу Васе, который живет в городе М. От города П до города М Петя решил доехать на поезде и взять с собой в подарок как можно больше коробок вкусных конфет.

Каждая коробка конфет имеет размер a × b × c сантиметров, где a – длина, b – ширина и c – высота коробки. Для перевозки конфет Петя хочет использовать один большой ящик в форме прямоугольного параллелепипеда. В ящик должны быть уложены все коробки конфет. Для того чтобы не повредить их, все коробки в ящике должны сохранять исходную ориентацию и располагаться в одном направлении. Петя может использовать ящик любого размера, но по правилам железнодорожных перевозок размер ящика по сумме трех измерений не может превышать N сантиметров.

Требуется написать программу, которая по заданным числам N, a, b и с определяет такой размер ящика, который должен использовать Петя, чтобы в него поместилось максимальное количество коробок конфет.

Ограничение времени: 2 секунды

Ограничение памяти: 256Mb

Формат ввода: Первая строка входного файла содержит разделенные пробелами четыре целых числа: N, a, b, с (1 ≤ N, a, b, c ≤ 109).

Формат вывода: Выходной файл должен содержать три числа – длину, ширину и высоты ящика, который должен выбрать Петя и в который поместится максимальное количество коробок конфет. Если подходящих ответов несколько, необходимо вывести любой.

Примеры:

Input1: 10 1 2 3 Output1: 3 4 3

Input2: 14 8 3 2 Output2: 9 3 2

Примечания: В первом примере выгоднее всего взять ящик размером 3 × 4 × 3 сантиметров, в который поместится три коробки конфет в длину, две коробки конфет в ширину и одна коробка конфет в высоту.

Во втором примере для того, чтобы разместить хотя бы две коробки, нужен ящик размером хотя бы 8 × 3 × 4, у которого сумма измерений равна 15. Поэтому в подходящий ящик поместится максимум одна коробка конфет. В том числе для этого подходит ящик размером 9 × 3 × 2, хотя он и не является минимальным.

Система оценки и описание подзадач:

Подзадача 1 (20 баллов)

1 ≤ N ≤ 300

В этой подзадаче 10 тестов, каждый тест оценивается в 2 балла. Баллы за каждый тест начисляются независимо.

Подзадача 2 (20 баллов)

1 ≤ N ≤ 5000

В этой подзадаче 10 тестов, каждый тест оценивается в 2 балла. Баллы за каждый тест начисляются независимо.

Подзадача 3 (30 баллов)

1 ≤ N ≤ 100 000

В этой подзадаче 15 тестов, каждый тест оценивается в 2 балла. Баллы за каждый тест начисляются независимо.

Подзадача 4 (30 баллов)

1 ≤ N ≤ 109

В этой подзадаче 15 тестов, каждый тест оценивается в 2 балла. Баллы за каждый тест начисляются независимо.

Моё решение

N, a, b, c = map(int, input().split())
maxBoxsAmount = 0


for x in range(a, N + 1):
    for y in range(b, N - a + 1):
        for z in range(c, N - a - b + 1):
            if (x + y + z == N):
               
                n = (x // a) * (y // b) * (z // c)
                    
                if n >= maxBoxsAmount:
                    maxBoxsAmount = n
                    m, l, k = x, y, z
                   
print(m, l, k)


# stdout:
# 18


# stderr:

# sample test 1 : ok
# sample test 2 : ok

# group 1 scored for 18 points
# group 2 scored for 0 points
# group 3 scored for 0 points
# group 4 scored for 0 points

# total: 18 points

Ответы

▲ 0

Пусть x, y, и z - количество коробок в укладке по измерениям a>=b>=c соответственно.

Нужен всего один цикл по наибольшему из размеров (а) "for x in range(1, (N-b-c)//a)" для поиска максимума функции x*y*z, где y и z в каждом шаге цикла определяется алгебраически как максимум функции y*(N-a*x-b*y)/c. Конечно, нужно проверить два целых значения для y вокруг максимума и взять то, которое даёт большее y*z.

Для больших N можно сделать дальнейшую оптимизацию. Исходя из того, что из всех прямоугольных параллелепипедов с заданной суммой длин сторон наибольший объём будет у куба, начинать поиск максимума в обе стороны нужно со значения x=(N//3)//a.