Подтема 3 из 7
Сколько чисел группы подходит
Как проверить «хотя бы одно», «ровно одно» и «не более двух из трёх» — часть задачи темы про четырёхзначные числа.
И, или, не
Как соединить несколько проверок?
требует, чтобы выполнились обе проверки, or — хотя бы одна, а not меняет ответ на противоположный. Проверим пары на свойство «число делится на 3»:
| Пара | x % 3 == 0 or y % 3 == 0 | x % 3 == 0 and y % 3 == 0 |
|---|---|---|
| (6, 5) | да | нет |
| (5, 9) | да | нет |
| (6, 9) | да | да |
| (5, 7) | нет | нет |
«Хотя бы одно» допускает, что подходят оба: пара (6, 9) подходит. Если нужно, чтобы делилось только одно число, это «ровно одно» — его разберём ниже.
Четырёхзначные числа
Какие из восьми чисел темы четырёхзначные?
Минус — не цифра: −1250 тоже четырёхзначное. Поэтому проверяют модуль: 1000 <= abs(x) <= 9999. Четырёхзначные у нас 1300, −1250, −2100, 2025 и 3000. Проверка без модуля пропустит −1250 и −2100: они меньше 1000.
for x in [1300, -1250, 7, 3000]: print(x, 1000 <= x <= 9999, 1000 <= abs(x) <= 9999)Сколько чисел подходит
Как проверить «не более двух из трёх элементов — четырёхзначные»?
Посчитай, сколько чисел тройки обладают свойством, и сравни это количество с числом из условия. Проверка даёт True или False, а int(True) = 1, int(False) = 0. Сложив три проверки, получим количество. Чтобы не повторять длинную проверку трижды, дадим ей имя — four:
def four(x): return 1000 <= abs(x) <= 9999 k = int(four(1300)) + int(four(-1250)) + int(four(-2100))print(k, k <= 2)def задаёт имя проверки, return — её ответ. В тройке 1300, −1250, −2100 все три числа четырёхзначные, и условие «не более двух» не выполнено. Любая формулировка про количество переводится так же:
- ни одного подходящего числа
k == 0- ровно одно
k == 1- ровно два
k == 2- все три
k == 3- хотя бы одно
k >= 1- хотя бы два
k >= 2- не более одного
k <= 1- не более двух
k <= 2подходят 0, 1 или 2 — не только 2- есть подходящие, но не все
0 < k < 3
Посчитаем k для всех троек темы:
| Тройка | Четырёхзначных | k <= 2 | Сумма |
|---|---|---|---|
| 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» подходят четыре тройки: вторая не проходит по четырёхзначным, последняя — по сумме. Наибольшая сумма по-прежнему 1707. В программе обе проверки соединяет and, а запись x, y, z = a[i], a[i + 1], a[i + 2] даёт имена трём числам тройки сразу:
def four(x): return 1000 <= abs(x) <= 9999 a = [125, 1300, -1250, -2100, 7, -325, 2025, 3000]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 <= 2025: sums.append(x + y + z)print(len(sums), max(sums))Скобки
Почему длинное условие иногда работает не так, как написано в задаче?
and выполняется раньше or, поэтому часть условия с or берут в скобки. Пусть нужно: «хотя бы одно число пары делится на три, а сумма пары больше 100». Проверим на паре (9, 20) с суммой 29:
x = 9y = 20print((x % 3 == 0 or y % 3 == 0) and x + y > 100)print(x % 3 == 0 or y % 3 == 0 and x + y > 100)Без скобок Python сначала проверил y % 3 == 0 and x + y > 100, и делимости 9 на три хватило, хотя сумма меньше 100. Длинное условие удобно разбить на части с именами: has_multiple = x % 3 == 0 or y % 3 == 0, large_sum = x + y > 100, затем if has_multiple and large_sum:.
Одно…, а другое…
Чем «хотя бы одно делится на три, и хотя бы одно меньше 10» отличается от «одно делится на три, а другое меньше 10»?
«Одно…, а другое…» требует, чтобы свойства были у двух разных чисел пары. Возьмём пару (3, 100). Число 3 и делится на три, и меньше 10, а 100 — ни то, ни другое. Вот три похожие формулировки:
- «хотя бы одно делится на три, и хотя бы одно меньше 10» —
(x % 3 == 0 or y % 3 == 0) and (x < 10 or y < 10): оба свойства может дать одно число; - «одно делится на три, а другое меньше 10» —
(x % 3 == 0 and y < 10) or (y % 3 == 0 and x < 10): проверяют оба распределения ролей; - «хотя бы одно одновременно делится на три и меньше 10» —
(x % 3 == 0 and x < 10) or (y % 3 == 0 and y < 10): оба свойства у одного числа.
Если оба числа обладают обоими свойствами, «одно…, а другое…» тоже выполнено: роли можно распределить любым способом. Пара при этом считается один раз — у нас одна проверка с or.
Итого
and,orобе проверки — хотя бы одна- Хотя бы однодопускает, что подходят оба
- Четырёхзначное
1000 <= abs(x) <= 9999 - Количество
k = int(…) + int(…) + int(…) - Не более двух
k <= 2; «не менее двух» —k >= 2 - Скобки
(… or …) and … - Одно…, а другое…два распределения ролей через or
Проверьте себя
Ответь сначала сам, потом открой ответ.
ОтветСкрыть ответ
ОтветСкрыть ответ
k — количество чётных чисел тройки. Переведи через k: «не менее двух чётных», «есть чётные, но не все», «ни одного чётного», «не более одного чётного».ОтветСкрыть ответ
k >= 2, 0 < k < 3, k == 0, k <= 1.x % 5 == 0 or y % 5 == 0 and x + y > 50 для пары (10, 12)? А правильная запись условия «хотя бы одно число кратно пяти, а сумма больше 50»?ОтветСкрыть ответ
True: Python сначала вычисляет and, а 10 делится на пять. Правильная запись (x % 5 == 0 or y % 5 == 0) and (x + y > 50) даёт False: сумма 22.T = 10. Проверь три условия: «хотя бы одно делится на три и хотя бы одно меньше T», «одно делится на три, а другое меньше T», «хотя бы одно одновременно делится на три и меньше T».ОтветСкрыть ответ
Практика
Для проверки ответов нужен JavaScript. Условия, подсказки и решения доступны ниже.
Пары с чётным числом
Последовательность 4, 7, 10, 3, −2. Найди количество соседних пар, где хотя бы одно число чётное, и максимальную сумму таких пар.
Введите через пробел количество пар, затем максимальную сумму.
Подсказка
«Хотя бы одно» — or: пара подходит и тогда, когда чётны оба числа.
Решение
Чётное число есть во всех четырёх парах; наибольшая сумма у пары (7, 10).
a = [4, 7, 10, 3, -2]sums = []for i in range(len(a) - 1): x, y = a[i], a[i + 1] if x % 2 == 0 or y % 2 == 0: sums.append(x + y)print(len(sums), max(sums))Ответ: 4 17
Тройки: два трёхзначных, сумма кратна 4
Для файла 17-1.txt определите количество троек, в которых ровно два числа трёхзначные по модулю, а сумма элементов тройки кратна 4, затем минимальную из сумм элементов таких троек. Под тройкой подразумевается три идущих подряд элемента последовательности.
Введите через пробел количество троек, затем минимальную сумму.
Подсказка
Трёхзначность проверяй у модуля каждого числа тройки; в ответе — наименьшая сумма.
Решение
Трёхзначное — 100 <= abs(x) <= 999: минус не цифра. Таких чисел в тройке должно быть ровно два.
def three(x): return 100 <= abs(x) <= 999 with open("17-1.txt") as f: a = [int(x) for x in f]sums = []for i in range(len(a) - 2): x, y, z = a[i], a[i + 1], a[i + 2] k = int(three(x)) + int(three(y)) + int(three(z)) if k == 2 and (x + y + z) % 4 == 0: sums.append(x + y + z)print(len(sums), min(sums))Ответ: 49 -10020
Ровно одно и хотя бы одно
Для файла 17-1.txt определите количество чисел, которые делятся ровно на одно из чисел 4 и 6, затем количество чисел, которые делятся хотя бы на одно из них. В ответе запишите два числа.
Введите через пробел количество чисел, кратных ровно одному из чисел 4 и 6, затем — хотя бы одному.
Подсказка
Посчитай выполненные проверки: k = int(x % 4 == 0) + int(x % 6 == 0).
Решение
«Ровно одно» — k == 1, «хотя бы одно» — k >= 1. Числа, кратные 12, входят только во второе количество.
with open("17-1.txt") as f: a = [int(x) for x in f]exactly = 0at_least = 0for x in a: k = int(x % 4 == 0) + int(x % 6 == 0) if k == 1: exactly += 1 if k >= 1: at_least += 1print(exactly, at_least)Ответ: 272 365
Хотя бы два делителя из трёх
Введите число.
Подсказка
Сложи три проверки делимости и сравни количество с двойкой.
Решение
«Хотя бы на два из трёх» — k >= 2, где k — количество выполненных проверок делимости.
with open("17-1.txt") as f: a = [int(x) for x in f]count = 0for x in a: k = int(x % 2 == 0) + int(x % 3 == 0) + int(x % 5 == 0) if k >= 2: count += 1print(count)Ответ: 282
Тройки с двумя трёхзначными
Последовательность 100, 5, 200, 300, 7, 400. Найди количество соседних троек, где ровно два числа трёхзначные, и максимальную сумму таких троек.
Введите через пробел количество троек, затем максимальную сумму.
Подсказка
Посчитай трёхзначные числа в каждой тройке; соседние тройки пересекаются.
Решение
Во всех четырёх тройках ровно два трёхзначных числа; наибольшая сумма у тройки 300, 7, 400.
def three(x): return 100 <= abs(x) <= 999 a = [100, 5, 200, 300, 7, 400]sums = []for i in range(len(a) - 2): x, y, z = a[i], a[i + 1], a[i + 2] k = int(three(x)) + int(three(y)) + int(three(z)) if k == 2: sums.append(x + y + z)print(len(sums), max(sums))Ответ: 4 707