Подтема 4 из 6
Ответ по центрам
Средние и минимумы координат центров, наименьший и наибольший кластер, объекты нужного вида, исключение кластера и целая часть произведения.
Среднее центров
Центры найдены. Как получить из них среднее координат?
Сложить координаты центров и разделить на число центров: каждый центр учитывается один раз, сколько бы точек ни было в его кластере. Для центров C₁ = (x₁; y₁), …, Cₖ = (xₖ; yₖ) это Pₓ = (x₁ + … + xₖ) / k и P_y = (y₁ + … + yₖ) / k. Функции read_points (подтема 1) и center_sum (подтема 3) считаем определёнными выше.
Сумму удобно записать коротко: sum(c[0] for c in centers) по очереди берёт первую координату каждого центра и складывает — это . Те же скобки работают в min и max, а в квадратных скобках получается :
centers = [(-4, 10), (6, 2)] xs = [c[0] for c in centers]print(xs)px = sum(c[0] for c in centers) / len(centers)py = sum(c[1] for c in centers) / len(centers)print(px, py)Даже если в одном кластере 100 точек, а в другом 5 000, их центры входят в среднее одинаково. Усреднять все точки файла или умножать центр на размер кластера не нужно.
Минимальные координаты
А если в условии просят минимальные координаты центров?
Минимум ищут по каждой координате отдельно; пара минимумов не обязана быть центром.
px = min(c[0] for c in centers)py = min(c[1] for c in centers)print(px, py)У центров (−4; 10) и (6; 2) наименьшая абсцисса −4, наименьшая ордината 2. Точки (−4; 2) среди центров нет — и не должно быть: условие просит два отдельных числа.
Маленький и большой кластер
Как найти центры самого маленького и самого большого кластера?
Сначала упорядочить кластеры по размеру — sorted(clusters, key=len), — и только потом искать центры: так центр не оторвётся от своего кластера. значит «сравнивать кластеры по длине», то есть по числу точек. Функцию len передают без скобок: мы говорим, чем мерить, а не вызываем её.
После сортировки clusters[0] — самый маленький, clusters[-1] — самый большой: индекс −1 означает последний элемент. Кластеры файла example27.txt — левый из пяти точек и правый из трёх:
clusters = [ [(0, 0), (0, 2), (1, 1), (2, 0), (2, 2)], [(10, 0), (12, 0), (11, 1)]]clusters = sorted(clusters, key=len)centers = [center_sum(c) for c in clusters] print([len(c) for c in clusters], centers)print(dist(centers[0], centers[-1]))Последняя строка — расстояние между центрами самого маленького и самого большого кластеров. Если сначала найти центры, а потом переставить только кластеры, центры останутся в старом порядке и перепутаются.
Объекты нужного вида
Как выбрать кластер, в котором больше всего звёзд нужного вида?
Сделать ключом сортировки свою функцию: она получает кластер и возвращает, сколько в нём объектов нужного вида. В обеих задачах основной волны ЕГЭ-2026 нужен кластер, где больше или меньше всего звёзд определённого вида, — это не то же самое, что самый большой кластер. Разделим звёзды файла 27-3.txt по границам из подтемы 2 и посчитаем красных гигантов. Функции read_stars и parse_kind — из подтемы 1:
def split_stars(stars): clusters = [[], [], []] for s in stars: if s[1] < 5: clusters[0].append(s) elif s[0] < 10: clusters[1].append(s) else: clusters[2].append(s) return clusters def red_giants(cluster): count = 0 for s in cluster: cls, sub, lum = parse_kind(s[2]) if cls == "M" and lum == "III": count += 1 return countclusters = split_stars(read_stars("27-3.txt"))print([len(c) for c in clusters])print([red_giants(c) for c in clusters]) by_red = sorted(clusters, key=red_giants)print(len(by_red[0]), len(by_red[-1]))Меньше всего красных гигантов (9) — в кластере из 172 звёзд, больше всего (17) — в кластере из 198, хотя самый большой кластер — из 231 звезды.
Исключение кластеров
Как исключить из ответа самый маленький кластер?
Отсортировать кластеры по размеру и отрезать лишний срезом, а среднее делить на новое число кластеров.
clusters = sorted(clusters, key=len)clusters = clusters[1:] # без самого маленького# clusters[:-1] — без самого большогоСрез [1:] берёт всё, начиная со второго элемента, [:-1] — всё, кроме последнего. Потом считают характеристики оставшихся кластеров и делят на их число: sum(radii) / len(radii), а не на исходное.
Читай условие точно — это три разных правила: удалить один самый маленький кластер; удалить все кластеры наименьшего размера; удалить все кластеры, где точек меньше заданного числа.
Целая часть
Как превратить дробный результат в ответ?
int(value * 10000) отбрасывает дробную часть, а модуль берут на том шаге, который назван в условии. 2,718281 · 10 000 = 27 182,81, ответ 27182. Заменить int на round нельзя, а у отрицательных чисел int идёт к нулю, а floor — вниз:
from math import floor print(int(2.718281 * 10000))print(int(2.9), round(2.9))print(int(-2.9), floor(-2.9))«Целая часть модуля» — это int(abs(value) * 10000). Но где брать модуль, решает условие. Абсциссы центров −6 и 4: модуль среднего |(−6 + 4) / 2| = 1, а среднее модулей (6 + 4) / 2 = 5. Так же различаются abs(min(values)) и min(abs(v) for v in values):
values = [-8, 3]print(abs(min(values)), min(abs(v) for v in values))Дробные числа и точность
float хранит многие десятичные дроби приближённо, поэтому ничего не округляй по дороге: ни координаты, ни центры перед усреднением. Целую часть берут один раз — у итогового значения. Множитель тоже читай в условии: бывает 100, 1 000, 10 000 или разные множители для разных величин.
Не добавляй «для надёжности» 0.0001. Если итог подозрительно близок к целому, пересчитай точнее — например, сложи расстояния функцией math.fsum, она меньше ошибается при сложении.
Полный пример
Как выглядит решение целиком, от файла до ответа?
Четыре шага подряд: прочитать, разделить, найти центры, собрать ответ — каждый шаг уже разобран в своей подтеме. Учебная задача: точки файла example27.txt образуют два кластера — левее и правее x = 5; центр — точка с наименьшей суммой расстояний; нужны целые части средних координат центров, умноженных на 10 000.
X Y0 00 21 12 02 210 012 011 1from math import dist def read_points(filename): points = [] with open(filename, encoding="utf-8-sig") as f: f.readline() # в этом файле есть заголовок X Y for line in f: if line.strip(): x, y = line.replace(",", ".").split() points.append((float(x), float(y))) return points def center_sum(cluster): best_point = cluster[0] best_sum = float("inf") for candidate in cluster: total = 0.0 for point in cluster: total += dist(candidate, point) if total < best_sum: best_sum = total best_point = candidate return best_point points = read_points("example27.txt")clusters = [[], []]for x, y in points: if x < 5: clusters[0].append((x, y)) else: clusters[1].append((x, y)) centers = [center_sum(c) for c in clusters]px = sum(c[0] for c in centers) / len(centers)py = sum(c[1] for c in centers) / len(centers)print(centers)print(int(px * 10000), int(py * 10000))Центры — (1; 1) и (11; 1), средние координаты Pₓ = (1 + 11) / 2 = 6 и P_y = 1, ответ 60000 10000. Граница x = 5 подходит именно этому файлу — в другом её снова находят по рисунку.
Другой способ · необязательноПроверка центров вручную
Левый кластер — (0; 0), (0; 2), (1; 1), (2; 0), (2; 2). От (1; 1) до четырёх углов по √2: сумма 4√2 ≈ 5,657. У любого угла сумма 2 + 2 + 2√2 + √2 = 4 + 3√2 ≈ 8,243 — больше.
Правый кластер — (10; 0), (12; 0), (11; 1). У (11; 1) сумма √2 + √2 = 2√2 ≈ 2,828, у двух других 2 + √2 ≈ 3,414.
Итого
- Среднее центров
sum(c[0] for c in centers) / len(centers) - Минимумыпо каждой координате отдельно
- По размеру
sorted(clusters, key=len), потом центры - Нужный видключ сортировки — своя функция подсчёта
- Исключение
[1:]или[:-1]; делить на новое число - Целая часть
int(value * 10000); модуль — где сказано
Проверьте себя
Ответь сначала сам, потом открой ответ.
ОтветСкрыть ответ
ОтветСкрыть ответ
ОтветСкрыть ответ
int(-2.718281 * 10000), floor(-2.718281 * 10000) и int(abs(-2.718281) * 10000)?ОтветСкрыть ответ
G, светимость V) в каждом кластере файла 27-3.txt? Сколько всего звёзд в кластере, где жёлтых карликов больше всего?ОтветСкрыть ответ
Практика
Для проверки ответов нужен JavaScript. Условия, подсказки и решения доступны ниже.
Средние координаты двух центров
Центры кластеров равны (-2, 4) и (6, 10). Найди средние координаты центров.
Введите два числа через пробел в том порядке, в каком их спрашивают.
Подсказка
Каждая координата усредняется отдельно.
Решение
(2, 7).
Решение программой
centers = [(-2, 4), (6, 10)]px = sum(c[0] for c in centers) / len(centers)py = sum(c[1] for c in centers) / len(centers)print(f'{px:g} {py:g}')Ответ: 2 7
Модуль среднего и среднее модулей
Абсциссы центров равны −6, 2 и 1. Чему равен модуль их среднего и чему — среднее их модулей?
Введите два числа через пробел: модуль среднего, затем среднее модулей.
Подсказка
Порядок действий меняет ответ.
Решение
Среднее (−6 + 2 + 1) / 3 = −1, его модуль 1; среднее модулей (6 + 2 + 1) / 3 = 3.
Решение программой
xs = [-6, 2, 1]mean_abs = sum(abs(x) for x in xs) / len(xs)print(f'{abs(sum(xs) / len(xs)):g} {mean_abs:g}')Ответ: 1 3
Модули минимальных координат
Центры равны (-5, 3), (2, -7) и (4, 1). Требуется модуль минимальной абсциссы и модуль минимальной ординаты. Какие два значения получатся?
Введите два числа через пробел в том порядке, в каком их спрашивают.
Подсказка
Сначала минимум, потом модуль.
Решение
5 и 7. Сначала ищем минимумы (−5 и −7), затем берём модули.
Решение программой
centers = [(-5, 3), (2, -7), (4, 1)]print(abs(min(c[0] for c in centers)), abs(min(c[1] for c in centers)))Ответ: 5 7
Среднее после исключения
После исключения одного кластера остались радиусы 2, 3, 7. На какое число нужно делить их сумму и чему равно среднее?
Введите два числа через пробел: делитель и среднее.
Подсказка
Делят на число оставшихся кластеров.
Решение
На 3; среднее равно 4.
Решение программой
radii = [2, 3, 7]print(len(radii), f'{sum(radii) / len(radii):g}')Ответ: 3 4
Аномалии и исключение кластера
В файле 27-2.txt записаны точки трёх кластеров и три аномалии. Для этого файла найди: а) модуль минимальной абсциссы и модуль минимальной ординаты центров кластеров; б) среднюю точку центров всех кластеров, кроме кластера с наименьшим числом точек. В ответе для каждого пункта запиши целые части произведений двух найденных чисел на 10 000.
Введите четыре целых числа через пробел: два для пункта а, затем два для пункта б.
Подсказка
Аномалии не входят ни в одну область; без самого маленького кластера остаются два центра.
Решение
а) 41224 27626: минимальная абсцисса −4,122474, минимальная ордината −2,762693; б) 5585 60949.
Решение программой
from math import dist def read_points(filename): points = [] with open(filename, encoding='utf-8-sig') as f: for line in f: parts = line.replace(',', '.').split() points.append((float(parts[0]), float(parts[1]))) return points def center_sum(cluster): best_point = cluster[0] best_sum = float('inf') for candidate in cluster: total = 0.0 for point in cluster: total += dist(candidate, point) if total < best_sum: best_sum = total best_point = candidate return best_point clusters = [[], [], []]for x, y in read_points('27-2.txt'): if -8 < x < 0 and 2 < y < 10: clusters[0].append((x, y)) elif 1 < x < 10 and 2 < y < 10: clusters[1].append((x, y)) elif -2 < x < 5 and -7 < y < 1: clusters[2].append((x, y))clusters.sort(key=len)centers = [center_sum(c) for c in clusters] min_x = abs(min(c[0] for c in centers))min_y = abs(min(c[1] for c in centers))mx = (centers[1][0] + centers[2][0]) / 2my = (centers[1][1] + centers[2][1]) / 2print(int(min_x * 10000), int(min_y * 10000), int(mx * 10000), int(my * 10000))Ответ: 41224 27626 5585 60949
Средняя точка центров
В файле 27-1.txt записаны точки двух кластеров. Центр кластера — его точка с наименьшей суммой расстояний до остальных точек кластера. Найди Pₓ — среднее арифметическое абсцисс центров и P_y — среднее арифметическое ординат центров. В ответе запиши целые части произведений Pₓ · 10 000 и P_y · 10 000.
Введите два целых числа через пробел.
Подсказка
Центры двух кластеров, затем средние координаты.
Решение
63837 29978.
Решение программой
from math import dist def read_points(filename): points = [] with open(filename, encoding='utf-8-sig') as f: for line in f: parts = line.replace(',', '.').split() points.append((float(parts[0]), float(parts[1]))) return points def center_sum(cluster): best_point = cluster[0] best_sum = float('inf') for candidate in cluster: total = 0.0 for point in cluster: total += dist(candidate, point) if total < best_sum: best_sum = total best_point = candidate return best_point left, right = [], []for p in read_points('27-1.txt'): if p[0] < 6: left.append(p) else: right.append(p) c1, c2 = center_sum(left), center_sum(right)px = (c1[0] + c2[0]) / 2py = (c1[1] + c2[1]) / 2print(int(px * 10000), int(py * 10000))Ответ: 63837 29978