Kattis: "watering Grass" Interval covering problem, why is my code so slow?

В настоящее время я практикуюсь, выполняя эту задачу на Python: https://open.kattis.com/problems/grass

Он работает так, как должен, вывод хорош, но продолжает работать слишком медленно. Я пробовал перемещать некоторые вещи, но ничего не работает. Я добавил довольно много кода, но я пытаюсь следовать принципу наименее функциональных фрагментов кода, чтобы кто-то мог запустить это сам.

Я использую некоторый синтаксический анализ, чтобы рассматривать круги как подинтервалы (голова, хвост) в большом интервале, который должен быть покрыт.

# Getmax is used in the algorithm to find the largest tail of all subintervals
def getmax(liste, t):
    big = -1
    start = None
    indexOfNewT = 0
    for n in range(len(liste)):
        if liste[n][0] <= t:

            if liste[n][1] >= big:
                big = liste[n][1]
                start = liste[n][0]
                indexOfNewT = n
    # In order to get a smaller list that i need to find a large tail in, I remove the elements that I add
    del liste[indexOfNewT]
    res = (start, big)
    if start == None:
        return None, None, None
    return big, res, liste


 # Here is the actual algorithm that solves the issue. 'Intervals' is a list of sublists which all
 #contain n numbers of intervals [start,end]. Lowerbound, upperBound are numbers indicating length of 
 #Grass field (Lowerbound is always 0)  
 #I was wondering whether the sorting could be done in a more clever way?
 def solver(lowerbound, upperBound, Intervals):
    Intervals.sort(key=lambda x: x[1])
    S = []
    t = lowerbound

    if (Intervals[len(Intervals)-1][1] < upperBound):
        return -1
    while t < upperBound:
        # getmax, her leder vi efter den største hale på et interval, mens head
        # på samme interval ikke er mere end det sidst addede element (t)
        get, i, newlist = getmax(Intervals, t)
        Intervals = newlist
        if get is None:
            return -1
        S.append(i)
        t = get
    return len(S)


    #method for converting circles to intervals with a head and a tail coordinate 
def getB(a, c):
    inter = abs(c * c - a * a)

# Here we actually parse the input, this method also calls the actual algorithm and provides output
#for every test case
def parse():
Innerintervals = []
# this is the loop that reads lines, if the line has more than three elements, it indicates a new 
# test case is coming. The reading itself happens at O(n) i dont think i could do better, could I?
for line in sys.stdin:
    current = line.split()
    if (len(current)) >= 3:
        if Innerintervals:
           # the algorithm is directly executed and printed as a test case is read
           print(solver(0, grassLen, Innerintervals))

        grassLen = float(current[1])
        width = float(current[2])
        Innerintervals = []

    else:
        linesplit = line.split()
        #Using a bit of pythagoras to get the places where the circle touches the edges of the field
        # I use this to be able to treat this a a interval covering problem
        position = int(linesplit[0])
        radius = int(linesplit[1])
        lenOfB = getB(width/2,radius)
        IntervalMin = position - lenOfB
        IntervalMax = position + lenOfB
        Innerintervals.append([IntervalMin,IntervalMax])


# as a result of my loop being constructed a bit clumsy, the last element is executed here
print(solver(0, grassLen, Innerintervals))

#running parse to starte the whole thing
parse()

Я бы очень хотел получить несколько советов, на случай, если какой-либо код "воняет" или если его можно оптимизировать где-нибудь, где я мог бы сделать некоторые очевидные промахи.

0 ответов

Другие вопросы по тегам