Cod sursa(job #2492592)

Utilizator Natasa_CNatasa Cirstea Natasa_C Data 14 noiembrie 2019 23:13:31
Problema Cele mai apropiate puncte din plan Scor 10
Compilator py Status done
Runda Arhiva educationala Marime 2.21 kb
from operator import itemgetter
from decimal import Decimal, ROUND_HALF_DOWN
import math


class Punct:
    def __init__(self, distanta, p1, p2):
        self.distanta = distanta
        self.p1 = p1
        self.p2 = p2

    def change(self, distanta, p1, p2):
        self.distanta = distanta
        self.p1 = p1
        self.p2 = p2

    def print_punct(self):
        print(self.distanta, self.p1, self.p2)


def get_dist(a, b):
    return (a[0] - b[0])*(a[0] - b[0]) + (a[1] - b[1])*(a[1] - b[1])


def distanta(st, dr):
    if dr - st <= 3:
        d = Punct(get_dist(x[st], x[st+1]), x[st], x[st+1])

        for i in range(st, dr):
            for j in range(i+1, dr+1):
                d_min = get_dist(x[i], x[j])
                if d_min < d.distanta:
                    d.change(d_min, x[i], x[j])

        return d
    else:
        middle = st + (dr - st)//2

        # calculate minimum distance in the left part and in the right part
        ds = distanta(st, middle)
        dd = distanta(middle, dr)

        # calculate the minimum distance in both parts
        if ds.distanta < dd.distanta:
            d = ds
        else:
            d = dd

        # form the band
        band = []
        for i in range(st, dr+1):
            if x[i][0] >= (x[middle][0] - d.distanta) and x[i][0] <= (x[middle][0] + d.distanta):
                band.append(x[i])

        band.sort(key=itemgetter(1))

        # calculate distances between points situated in the band
        for i in range(len(band) - 7):
            for j in range(i+1, i+8):
                dist = get_dist(band[i], band[j])
                if dist < d.distanta:
                    d.change(dist, band[i], band[j])
        return d


x = []
f = open("cmap.in", "r")

if f.mode == 'r':
    f1 = f.readlines()
    f.close()

    n = int((f1[0].split())[0])

    for i in range(n):
        line = f1[i+1].split()
        x.append([int(line[0]), int(line[1])])

    x.sort(key=itemgetter(0))

    p = distanta(0, n-1)

    aux = math.sqrt(p.distanta)
    aux = Decimal(aux)
    aux = Decimal(aux.quantize(Decimal('0.000001'), rounding=ROUND_HALF_DOWN))

    p.change(aux, p.p1, p.p2)
    # p.print_punct()

    fw = open("cmap.out", "w")
    fw.write(str(p.distanta))
    fw.close()