Cod sursa(job #3333724)

Utilizator razvanfintaRazvan Fintaneanu razvanfinta Data 14 ianuarie 2026 22:46:24
Problema Bibel Scor 0
Compilator py Status done
Runda Arhiva de probleme Marime 2.68 kb
def rezolva():
    # citesc datele de intrare din fisier
    with open("bibel.in", "r") as f:
        linii = f.readlines()
    
    # procesez fiecare linie
    bile = []  # lista de bile acumulate
    rezultate = []
    
    for linie in linii:
        parti = linie.strip().split()
        
        if parti[0] == '0':
            # adaug o bila noua
            x = int(parti[1])
            y = int(parti[2])
            bile.append((x, y))
        
        elif parti[0] == '1':
            # sfarsit de nivel - calculez timpul minim pentru a colecta toate bilele
            if len(bile) == 0:
                rezultate.append(0)
                continue
            
            n = len(bile)
            
            # calculez distanta patrat intre fiecare pereche de bile
            # includ si originea (0, 0) ca pozitia de start
            def dist_patrat(p1, p2):
                return (p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2
            
            # programare dinamica pe masca de biti pentru problema comis-voiajorului
            # dp[masca][i] = cost minim pentru a colecta bilele din masca, terminand la bila i
            inf = float('inf')
            dp = []
            for masca in range(1 << n):
                dp.append([inf] * n)
            
            # initializez: pornesc din origine (0,0) si merg la fiecare bila
            origine = (0, 0)
            for i in range(n):
                dp[1 << i][i] = dist_patrat(origine, bile[i])
            
            # completez dp
            for masca in range(1, 1 << n):
                for ultim in range(n):
                    if not (masca & (1 << ultim)):
                        continue
                    if dp[masca][ultim] == inf:
                        continue
                    
                    # incerc sa merg la o bila noua
                    for urmator in range(n):
                        if masca & (1 << urmator):
                            continue
                        
                        masca_noua = masca | (1 << urmator)
                        cost_nou = dp[masca][ultim] + dist_patrat(bile[ultim], bile[urmator])
                        
                        if cost_nou < dp[masca_noua][urmator]:
                            dp[masca_noua][urmator] = cost_nou
            
            # gasesc costul minim pentru a colecta toate bilele
            masca_finala = (1 << n) - 1
            cost_min = min(dp[masca_finala])
            rezultate.append(cost_min)
        
        elif parti[0] == '2':
            # sfarsit de joc
            break
    
    # scriu rezultatele in fisier
    with open("bibel.out", "w") as f:
        for rez in rezultate:
            f.write(f"{rez}\n")


rezolva()