Задача Задача №3158975
А
А
Давайте разберём обе задачи подробно и шаг за шагом.
Задача 1: Максимальное количество решённых задач на олимпиаде
Условие:
- Есть
nзадач. - Время на выполнение всей олимпиады —
tминут. - Для каждой задачи
iизвестно времяa_i. - Можно выбрать любую задачу
iи решать её последовательно, начиная с неё, до конца задач и пока не закончится времяt. - Нужно определить максимальное количество задач, которые можно решить, начиная с любой задачи.
Подход к решению:
- Понимание задачи:
- Можно выбрать любую задачу
i. - Решать задачи с
iпоn. - Общее время для решения задач с
iдоk— суммаa_i + a_{i+1} + ... + a_k. - Нужно найти такой
i, для которого суммаa_i + ... + a_jмаксимально возможна, не превышаяt, и при этомjмаксимально возможен.
- Можно выбрать любую задачу
План решения:
Протяженный случай и эффективность:
- Время
nможет быть до10^5. - Значит, простой перебор всех вариантов с вложенными циклами не подойдет из-за ограничения времени.
- Можно использовать Два указателя (two-pointer) для эффективного подсчёта суммы на подотрезках.
- Время
Два указателя:
- Изначально оба указателя (
leftиright) указывают на начало массива. - Расширяем
right, добавляяa[right], пока сумма не превыситt. - Как только сумма превысит
t, сдвигаемleft, убирая из суммыa[left]. - В каждый момент времени запоминаем длину текущего интервала, если он допустим.
- В конце перебираем все возможные интерваллы, чтобы найти максимум.
- Изначально оба указателя (
Код решения:
n, t = map(int, input().split())
a = list(map(int, input().split()))
left = 0
current_sum = 0
max_tasks = 0
for right in range(n):
current_sum += a[right]
while current_sum > t:
current_sum -= a[left]
left += 1
max_tasks = max(max_tasks, right - left + 1)
print(max_tasks)
Объяснение кода:
- Инициализация
left = 0,current_sum = 0. - Проходим по
rightот 0 доn-1. - Добавляем
a[right]к текущей сумме. - Пока сумма превышает
t, сдвигаемleftи убираемa[left]из суммы. - Обновляем максимум задач, которые можно решить начиная с
leftи ending сright.
Задача 2: Выбор финалистов по баллам
Условие:
- Есть список участников с именами и баллами.
- Необходимо вывести всех участников, набравших не менее
Xбаллов. - Отсортировать их по имени в лексикографическом порядке.
- Если никто не прошёл, вывести
-1.
План решения:
- Вводим число участников
n. - Считываем список участников (
имя,балл). - Вводим проходной балл
X. - Отбираем участников, у которых балл >=
X. - Если таких участников нет, выводим
-1. - Иначе сортируем их по имени и выводим.
Код решения:
n = int(input())
participants = []
for _ in range(n):
line = input().split()
name = line[0]
score = int(line[1])
participants.append((name, score))
X = int(input())
# Отбираем участников, набравших не менее X
finalists = [p for p in participants if p[1] >= X]
if not finalists:
print(-1)
else:
# Сортируем по имени
finalists.sort(key=lambda x: x[0])
print(len(finalists))
for name, score in finalists:
print(name, score)
Итог:
- Первая задача — использование двух указателей.
- Вторая задача — фильтрация и сортировка.
Если требуется, я могу помочь с более подробным разбором или объяснением любого из пунктов!