Задания
Версия для печати и копирования в MS Word
Тип 27 № 84689
i

Фраг­мент звёзд­но­го неба спро­еци­ро­ван на плос­кость с де­кар­то­вой си­сте­мой ко­ор­ди­нат. Учёный решил про­ве­сти кла­сте­ри­за­цию по­лу­чен­ных точек, яв­ля­ю­щих­ся изоб­ра­же­ни­я­ми звёзд, то есть раз­бить их мно­же­ство на N не­пе­ре­се­ка­ю­щих­ся не­пу­стых под­мно­жеств (кла­сте­ров), таких что точки каж­до­го под­мно­же­ства лежат внут­ри пря­мо­уголь­ни­ка со сто­ро­на­ми дли­ной H и W, причём эти пря­мо­уголь­ни­ки между собой не пе­ре­се­ка­ют­ся. Сто­ро­ны пря­мо­уголь­ни­ков не обя­за­тель­но па­рал­лель­ны ко­ор­ди­нат­ным осям.

Га­ран­ти­ру­ет­ся, что такое раз­би­е­ние су­ще­ству­ет и един­ствен­но для за­дан­ных раз­ме­ров пря­мо­уголь­ни­ков.

Диа­мет­ром кла­сте­ра назовём мак­си­маль­ное рас­сто­я­ние между двумя точ­ка­ми в кла­сте­ре. Для каж­до­го кла­сте­ра га­ран­ти­ру­ет­ся, что диа­метр об­ра­зу­ет един­ствен­ная пара точек. Рас­сто­я­ние между двумя точ­ка­ми на плос­ко­сти A(x1; y1) и B(x2; y2) вы­чис­ля­ет­ся по фор­му­ле:

 d левая круг­лая скоб­ка A; B пра­вая круг­лая скоб­ка = ко­рень из: на­ча­ло ар­гу­мен­та: левая круг­лая скоб­ка x_2 минус x_1 пра­вая круг­лая скоб­ка в квад­ра­те плюс левая круг­лая скоб­ка y_2 минус y_1 пра­вая круг­лая скоб­ка в квад­ра­те конец ар­гу­мен­та .

В файле А хра­нят­ся дан­ные о звёздах двух кла­сте­ров, где H  =  3, W  =  4 для каж­до­го кла­сте­ра. В каж­дой стро­ке за­пи­са­на ин­фор­ма­ция о рас­по­ло­же­нии на карте одной звез­ды: сна­ча­ла ко­ор­ди­на­та x, затем ко­ор­ди­на­та  y. Зна­че­ния даны в услов­ных еди­ни­цах. Из­вест­но, что ко­ли­че­ство звёзд не пре­вы­ша­ет 1000.

В файле Б хра­нят­ся дан­ные о звёздах трёх кла­сте­ров, где H  =  6, W  =  5 для каж­до­го кла­сте­ра. Из­вест­но, что ко­ли­че­ство звёзд не пре­вы­ша­ет 10 000. Струк­ту­ра хра­не­ния ин­фор­ма­ции о звёздах в файле Б ана­ло­гич­на файлу А.

Файл А

Файл Б

Из­вест­но, что в файле Б име­ют­ся ко­ор­ди­на­ты ровно трёх «лиш­них» точек, яв­ля­ю­щих­ся ано­ма­ли­я­ми, воз­ник­ши­ми в ре­зуль­та­те помех при пе­ре­да­че дан­ных. Эти три точки не от­но­сят­ся ни к од­но­му из кла­сте­ров, их учи­ты­вать не нужно.

Для файла А най­ди­те пары точек, ко­то­рые об­ра­зу­ют диа­метр каж­до­го кла­сте­ра. Затем вы­чис­ли­те два числа: Px  — ми­ни­маль­ную из сумм абс­цисс этих точек для всех кла­сте­ров и Py  — ми­ни­маль­ную из сумм ор­ди­нат этих точек для всех кла­сте­ров. Для файла Б най­ди­те два числа: Q1  — диа­метр кла­сте­ра с ми­ни­маль­ным ко­ли­че­ством точек и Q2  — мак­си­маль­ное рас­сто­я­ние от точки, об­ра­зу­ю­щей диа­метр од­но­го кла­сте­ра, до точки, об­ра­зу­ю­щей диа­метр дру­го­го кла­сте­ра.

Га­ран­ти­ру­ет­ся, что во всех кла­сте­рах ко­ли­че­ство точек раз­лич­но.

В от­ве­те за­пи­ши­те че­ты­ре числа: в пер­вой стро­ке  — сна­ча­ла целую часть аб­со­лют­но­го зна­че­ния про­из­ве­де­ния Px × 10 000, затем целую часть аб­со­лют­но­го зна­че­ния про­из­ве­де­ния Py × 10 000; во вто­рой стро­ке  — сна­ча­ла целую часть про­из­ве­де­ния Q1 × 10 000, затем целую часть про­из­ве­де­ния Q2 × 10 000.

Воз­мож­ные дан­ные од­но­го из фай­лов ил­лю­стри­ро­ва­ны гра­фи­ком.

Вни­ма­ние! Гра­фик при­ведён в ил­лю­стра­тив­ных целях для про­из­воль­ных зна­че­ний, не име­ю­щих от­но­ше­ния к за­да­нию.

Для вы­пол­не­ния за­да­ния ис­поль­зуй­те дан­ные из при­ла­га­е­мо­го файла.

Ответ:

Спрятать решение

Ре­ше­ние.

По­стро­им диа­грам­мы для файла А и Б. Для этого вос­поль­зу­ем­ся таб­лич­ным ре­дак­то­ром.

 

Диа­грам­ма для файла А:

Диа­грам­ма для файла Б:

 

 

При­ведём ре­ше­ние на языке Python для файла А.

from math import dist

f = open('27A.txt')

claster = [[] for i in range(2)]

for s in f:

x,y= map(float, s.split())

if x < 19:

claster[0].append((x,y))

else:

claster[1].append((x,y))

def diam(claster):

rad = []

for i in claster:

for j in claster:

rad.append([dist(i,j),[i,j]])

return max(rad)[1]

centr = [diam(i) for i in claster]

p1, p2 = centr[0]

p3, p4 = centr[1]

print(min((p1[0] + p2[0], p1[1] + p2[1]))*10000)

print(min((p3[0] + p4[0], p3[1] + p4[1]))*10000)

 

При­ведём ре­ше­ние на языке Python для файла В.

from math import dist

f = open('27B.txt')

claster = [[] for i in range(3)]

for s in f:

x,y= map(float, s.split())

if x > 20 and y > 25:

claster[0].append((x,y))

elif x < 0 and 10 > y > 5:

claster[1].append((x,y))

elif x < 0 and y < 0:

claster[2].append((x,y))

def diam(claster):

rad = []

for i in claster:

for j in claster:

rad.append([dist(i,j),[i,j]])

return max(rad)

 

D = [diam(i)[1] for i in claster]

k_c = [len(i) for i in claster]

Q1 = (([diam(i)[0] for i in claster])[k_c.index(min(k_c))])*10000

print(Q1)

 

Q2 = []

for i in range(len(D) - 1):

for j in range(i + 1, len(D)):

for p1 in D[i]:

for p2 in D[j]:

Q2.append(dist(p1,p2)*10000)

print(max(Q2))

 

 

Ответ: 145015 313020 29254 488624.

 

При­ведём ре­ше­ние Юрия Кра­силь­ни­ко­ва на языке Python.

ffrom math import dist # dist ра­бо­та­ет го­раз­до быст­рее, чем (x**2+y**2)**0.5

гра­ни­цыА = [[5,19,10,25],[20,12,25,20]]

гра­ни­цыБ = [[-10,-7,0,0],[-10,5,0,10],[25,25,35,35]]

# гра­ни­цы со­дер­жат для каж­до­го кла­сте­ра спи­сок [Xmin,Ymin,Xmax,Ymax]

# Чтобы со­ста­вить спис­ки, нужно от­крыть файл в LibreOffice Calc, по­стро­ить диа­грам­му X-Y

# и ви­зу­аль­но опре­де­лить гра­ни­цы ко­ор­ди­нат для каж­до­го кла­сте­ра.

def кла­сте­ри­за­ция(звез­ды,гра­ни­цы):

кла­сте­ры=[[] for _ in range(len(гра­ни­цы))]

for x,y in звез­ды:

внут­ри = [xmin <= x <= xmax and ymin <= y <= ymax for xmin,ymin,xmax,ymax in гра­ни­цы]

if sum(внут­ри) == 1: кла­сте­ры[внут­ри.index(True)].append([x,y])

elif sum(внут­ри) == 0: print('Звез­да',[x,y],'вне кла­сте­ров')

else: print('Ошиб­ка: не­од­но­знач­ные гра­ни­цы')

print('Кла­сте­ров:',len(кла­сте­ры),'звезд:',*[len(x) for x in кла­сте­ры])

return кла­сте­ры

def диа­метр(кла­стер):

макс_р = 0

for зв1 in кла­стер:

for зв2 in кла­стер:

д = dist(зв1,зв2)

if д > макс_р:

макс_р = д

ответ = [зв1,зв2]

return ответ

f=open('27A.txt')

print('За­да­ча А:')

звез­ды = [list(map(float,s.replace(',','.').split())) for s in f]

кла­сте­ры = кла­сте­ри­за­ция(звез­ды,гра­ни­цыА)

диа­мет­ры = [диа­метр(к) for к in кла­сте­ры]

px = int(min(диа­мет­ры[0][0][0]+диа­мет­ры[0][1][0],диа­мет­ры[1][0][0]+диа­мет­ры[1][1][0])*10000)

py = int(min(диа­мет­ры[0][0][1]+диа­мет­ры[0][1][1],диа­мет­ры[1][0][1]+диа­мет­ры[1][1][1])*10000)

print(px, py)

f=open('27B.txt')

print('За­да­ча Б:')

звез­ды = [list(map(float,s.replace(',','.').split())) for s in f]

кла­сте­ры = кла­сте­ри­за­ция(звез­ды,гра­ни­цыБ)

кла­сте­ры.sort(key=lambda x: len(x)) # по ко­ли­че­ству точек

диа­мет­ры = [диа­метр(к) for к in кла­сте­ры]

qx = int(dist(диа­мет­ры[0][0],диа­мет­ры[0][1])*10000)

рас­сто­я­ния = []

for д1 in range(len(диа­мет­ры)-1):

for д2 in range(д1+1,len(диа­мет­ры)):

for n1 in range(2):

for n2 in range(2):

рас­сто­я­ния.append(dist(диа­мет­ры[д1][n1],диа­мет­ры[д2][n2]))

qy = int(max(рас­сто­я­ния)*10000)

print(qx,qy)