Подтема 5 из 7
Порог по всей последовательности
Почему порог из условия находят до перебора троек — и задача темы целиком: ответ 8358 99821.
Сначала порог
Порог задачи темы — максимальный элемент, оканчивающийся на 25. Можно ли проверять тройки сразу, пока читаем числа по порядку?
Нет: число в конце файла может оказаться больше всех прежних и поднять порог — даже для самых первых троек. Поэтому сначала проходят весь список и находят порог, а потом перебирают тройки. Посмотри, как меняется наибольший элемент на 25, пока читаем восемь чисел темы:
Первая тройка 125, 1300, −1250 с суммой 175 подходит под порог 2025. Если сравнить её с порогом на момент чтения — 125, — она не пройдёт, и ответ на восьми числах получится 3 вместо 4.
Поэтому решение проходит по списку дважды: первый проход находит порог, второй перебирает тройки. Два прохода по 10 000 чисел программа делает мгновенно.
Отбор и характеристика
Как найти максимальный элемент, оканчивающийся на 25?
Сначала нужные числа отбирают в отдельный список, потом применяют к нему .
a = [125, 1300, -1250, -2100, 7, -325, 2025, 3000]ends = [x for x in a if abs(x) % 100 == 25]print(ends, max(ends))Это с условием: перебрать x из a и взять x, если он оканчивается на 25. В список кладут исходные числа: x, а не abs(x). Модуль нужен только для проверки окончания — иначе вместо −325 в списке окажется 325, а это другое число.
Из отобранного списка получают любую характеристику, которую спрашивает условие:
- максимальный такой элемент
max(ends)- минимальный такой элемент
min(ends)- количество таких элементов
len(ends)так считают порог «количество чисел, кратных 2042»- сумма таких элементов
sum(ends)
У пустого списка нет ни максимума, ни минимума: max([]) — ошибка. В файлах задания нужные числа есть, а иногда условие прямо это гарантирует.
Задача темы целиком
Теперь все части задачи на месте — как их собрать?
Порог находят до цикла, тройки проверяют в цикле, ответ выводят после цикла. Сначала — вручную на восьми числах темы, с порогом 2025:
| Тройка | Четырёхзначных | Сумма | Подходит? |
|---|---|---|---|
| 125, 1300, −1250 | 2 | 175 | да |
| 1300, −1250, −2100 | 3 | −2050 | нет: три четырёхзначных |
| −1250, −2100, 7 | 2 | −3343 | да |
| −2100, 7, −325 | 1 | −2418 | да |
| 7, −325, 2025 | 1 | 1707 | да |
| −325, 2025, 3000 | 2 | 4700 | нет: сумма больше 2025 |
На восьми числах ответ 4 1707. Программа для файла задачи темы:
def four(x): return 1000 <= abs(x) <= 9999 with open("17.txt") as f: a = [int(x) for x in f]limit = max([x for x in a if abs(x) % 100 == 25])sums = []for i in range(len(a) - 2): x, y, z = a[i], a[i + 1], a[i + 2] k = int(four(x)) + int(four(y)) + int(four(z)) if k <= 2 and x + y + z <= limit: sums.append(x + y + z)print(len(sums), max(sums))Ответ задачи темы: 8358 99821. Порог по файлу — 99825. Чтобы проверить программу, замени чтение файла строкой a = [125, 1300, -1250, -2100, 7, -325, 2025, 3000]: должно получиться 4 1707.
Среднее арифметическое
Порог бывает и средним — например, «меньше среднего арифметического всех чётных элементов последовательности». Как его считать?
Среднее считают по той группе, что названа в условии: сумма её чисел, делённая на их количество. Сравнивают без деления: вместо x < s / k пишут x * k < s. В последовательности 2, 9, 4, 7, 12 чётные числа 2, 4, 12, их сумма 18, количество 3, среднее 6:
a = [2, 9, 4, 7, 12]even = [x for x in a if x % 2 == 0]s = sum(even)k = len(even)print(s / k, 4 * k < s, 7 * k < s)4 меньше среднего, 7 — нет. Делить сумму чётных на длину всего списка нельзя: в знаменателе количество той же группы. Умножать обе части на k можно, потому что k положительно, а сравнение без деления точное — в нём нет дробей.
Исходный список не трогаем
Можно ли упростить перебор — отсортировать числа или выбросить неподходящие?
Нет: соседи есть только в исходном порядке. Сортировка и удаление чисел создают пары, которых в файле не было.
Отобрать отдельный список для порога можно — как ends выше. Но тройки перебирают в исходном списке a. И порог считают один раз, до цикла: если написать max(...) внутри цикла, программа будет заново проходить весь список на каждой тройке — 10 000 раз по 10 000 чисел.
Итого
- Порогпо всему списку, до перебора троек
- Отбор
[x for x in a if abs(x) % 100 == 25] - Исходные числав список —
x, а неabs(x) - Характеристика
max,min,len,sumотобранного списка - Среднее
x * k < sвместоx < s / k - Задача темы8358 99821; на восьми числах — 4 1707
Проверьте себя
Ответь сначала сам, потом открой ответ.
ОтветСкрыть ответ
ОтветСкрыть ответ
ОтветСкрыть ответ
x * 3 < 18.print(len([x for x in [10, -25, 125, 7] if abs(x) % 100 == 25]))?ОтветСкрыть ответ
ОтветСкрыть ответ
Практика
Для проверки ответов нужен JavaScript. Условия, подсказки и решения доступны ниже.
Порог — наибольший на 17
Последовательность 12, 117, 40, 217, 5. Найди наибольший элемент, оканчивающийся на 17, затем количество соседних пар с суммой больше него и максимальную такую сумму.
Введите через пробел порог, количество пар и максимальную сумму.
Подсказка
Сначала найди порог по всем числам, потом перебирай пары.
Решение
Порог 217 — последнее число на 17. Подходят пары (40, 217) и (217, 5).
a = [12, 117, 40, 217, 5]limit = max([x for x in a if abs(x) % 100 == 17])sums = []for i in range(len(a) - 1): s = a[i] + a[i + 1] if s > limit: sums.append(s)print(limit, len(sums), max(sums))Ответ: 217 2 257
Порог — количество кратных 25
Для файла 17-1.txt определите количество пар, в которых хотя бы одно число отрицательное, а сумма пары меньше количества чисел файла, кратных 25. В ответе запишите количество найденных пар, затем максимальную из сумм элементов таких пар. Под парой подразумевается два идущих подряд элемента.
Введите через пробел количество пар, затем максимальную сумму.
Подсказка
Сначала посчитай кратные 25 во всём файле, затем сравнивай с этим количеством сумму пары.
Решение
Порог — len([x for x in a if x % 25 == 0]), его находят до перебора пар.
with open("17-1.txt") as f: a = [int(x) for x in f]limit = len([x for x in a if x % 25 == 0])sums = []for i in range(len(a) - 1): x, y = a[i], a[i + 1] if (x < 0 or y < 0) and x + y < limit: sums.append(x + y)print(len(sums), max(sums))Ответ: 520 41
Задача темы
В файле 17.txt содержится последовательность целых чисел. Элементы последовательности могут принимать целые значения от −100 000 до 100 000 включительно. Определите количество троек элементов последовательности, в которых не более двух из трёх элементов являются четырёхзначными числами, а сумма элементов тройки не больше максимального элемента последовательности, оканчивающегося на 25. В ответе запишите количество найденных троек чисел, затем максимальную из сумм элементов таких троек. В данной задаче под тройкой подразумевается три идущих подряд элемента последовательности.
Введите через пробел количество троек, затем максимальную сумму.
Подсказка
Порог — max чисел, у которых abs(x) % 100 == 25; четырёхзначность — по модулю, «не более двух» — k <= 2.
Решение
Порог по файлу — 99825. Проверь программу на восьми числах темы: должно получиться 4 1707.
def four(x): return 1000 <= abs(x) <= 9999 with open("17.txt") as f: a = [int(x) for x in f]limit = max([x for x in a if abs(x) % 100 == 25])sums = []for i in range(len(a) - 2): x, y, z = a[i], a[i + 1], a[i + 2] k = int(four(x)) + int(four(y)) + int(four(z)) if k <= 2 and x + y + z <= limit: sums.append(x + y + z)print(len(sums), max(sums))Ответ: 8358 99821
Тройки и максимум на 21
В файле 17-2.txt содержится последовательность натуральных чисел, не превышающих 100 000. Определите количество троек, в которых ровно два числа четырёхзначные, хотя бы одно число делится на 7, а сумма элементов тройки больше максимального элемента последовательности, запись которого оканчивается на 21. В ответе запишите количество найденных троек, затем максимальную из сумм элементов таких троек. Под тройкой подразумевается три идущих подряд элемента.
Введите через пробел количество троек, затем максимальную сумму.
Подсказка
Порог — максимум чисел, оканчивающихся на 21; в тройке ровно два четырёхзначных и хотя бы одно кратное 7.
Решение
Три проверки тройки соединяет and; порог находят до цикла.
def four(x): return 1000 <= abs(x) <= 9999 with open("17-2.txt") as f: a = [int(x) for x in f]limit = max([x for x in a if x % 100 == 21])sums = []for i in range(len(a) - 2): x, y, z = a[i], a[i + 1], a[i + 2] k4 = int(four(x)) + int(four(y)) + int(four(z)) k7 = int(x % 7 == 0) + int(y % 7 == 0) + int(z % 7 == 0) if k4 == 2 and k7 >= 1 and x + y + z > limit: sums.append(x + y + z)print(len(sums), max(sums))Ответ: 13 104902
Меньше среднего чётных
Последовательность 6, 9, 2, 15, 4. Найди количество соседних пар, в которых одно число кратно трём, а другое меньше среднего арифметического всех чётных элементов, и максимальную сумму таких пар.
Введите через пробел количество пар, затем максимальную сумму.
Подсказка
«Одно…, а другое…» — два распределения ролей через or; среднее сравнивай без деления: y * k < s.
Решение
Среднее чётных 6, 2, 4 равно 4. Подходят (9, 2) и (2, 15); у пары (15, 4) другое число 4 не меньше 4.
a = [6, 9, 2, 15, 4]even = [x for x in a if x % 2 == 0]s, k = sum(even), len(even)sums = []for i in range(len(a) - 1): x, y = a[i], a[i + 1] if (x % 3 == 0 and y * k < s) or (y % 3 == 0 and x * k < s): sums.append(x + y)print(len(sums), max(sums))Ответ: 2 17
Среднее нечётных без деления
Для файла 17-2.txt определите количество пар, в которых одно число делится на 9, а другое меньше среднего арифметического всех нечётных элементов последовательности. В ответе запишите количество найденных пар, затем максимальную из сумм элементов таких пар. Под парой подразумевается два идущих подряд элемента.
Введите через пробел количество пар, затем максимальную сумму.
Подсказка
«y меньше среднего» — y * k < s, где s и k — сумма и количество нечётных.
Решение
Среднее нечётных сравнивают без деления; распределения ролей соединяет or.
with open("17-2.txt") as f: a = [int(x) for x in f]odd = [x for x in a if x % 2 != 0]s, k = sum(odd), len(odd)sums = []for i in range(len(a) - 1): x, y = a[i], a[i + 1] if (x % 9 == 0 and y * k < s) or (y % 9 == 0 and x * k < s): sums.append(x + y)print(len(sums), max(sums))Ответ: 190 99120