№27 · решено
Кластеры частиц по энергии, K = 4, R = 2,0
Частицы с координатами, скоростью, массой и признаком I–VII. Кластеризация по кинетической энергии E = m(Vx² + Vy²)/2, модуль разности энергий внутри кластера не больше R = 2,0, K = 4. Центр кластера — частица с минимальной суммой |ΔE| до остальных. Найди Q1 — наибольшее евклидово расстояние между частицами одного кластера с признаком II, и Q2 — наибольшую энергию центра кластера. В ответ: целые части Q1·10000 и Q2·10000.
Источник: ФИПИ, № 31521
Скачать файл: task_31521_A.txt. В редакторе он уже лежит рядом с кодом, открывай как на экзамене: open('task_31521_A.txt').
Ответвпиши то, что вывела программа
Показать разбор
- Посчитай у каждой частицы энергию E = m(Vx² + Vy²)/2. Кластеризуем по одному числу: в dist передаём список из одной энергии.
- Порог подбирай так, чтобы получилось ровно 4 кластера. Начни с малого t и смотри на размеры: цепочка соседей внутри кластера должна не рваться, а разные кластеры не должны склеиваться.
- В каждом кластере центр это частица с наименьшей суммой |ΔE| до остальных. В чётных кластерах таких частиц две с равной суммой: берём ту, у которой энергия больше, поэтому сумму округляем, чтобы погрешность дробных чисел не решала за нас.
- Q1: перебери пары частиц с признаком II внутри каждого кластера и возьми наибольшее евклидово расстояние по координатам.
- Q2: наибольшая энергия среди центров. Выведи целые части Q1·10000 и Q2·10000.
from math import dist
data = []
for line in open('task_31521_A.txt'):
x, y, vx, vy, m, h = line.replace(',', '.').split()
x, y, vx, vy, m = map(float, (x, y, vx, vy, m))
data.append(([0.5 * m * (vx * vx + vy * vy)], (x, y, h)))
clusters = []
while data:
clusters.append([data.pop(0)])
for p in clusters[-1]:
sosedi = [p1 for p1 in data if dist(p[0], p1[0]) < 0.7]
clusters[-1].extend(sosedi)
for p1 in sosedi:
data.remove(p1)
def centroids(cl):
m = []
for p in cl:
sm = sum(dist(p[0], p1[0]) for p1 in cl)
m.append([round(sm, 6), -p[0][0], p])
return min(m)[2]
Q1 = 0
for cl in clusters:
t2 = [p[1][:2] for p in cl if p[1][2] == 'II']
for a in t2:
for b in t2:
Q1 = max(Q1, dist(a, b))
Q2 = max(centroids(cl)[0][0] for cl in clusters)
print(int(Q1 * 10000), int(Q2 * 10000))