Wenn man dies als ein Baumproblem betrachtet, ist es ein roter Hering, es ist wirklich eine gerichtete Grafik. Aber vergiss das alles.
Denken Sie an ein Glas irgendwo unter dem oberen. Darüber befinden sich ein oder zwei Gläser, die überlaufen können. Mit der richtigen Wahl des Koordinatensystems (keine Sorge, siehe Ende) können wir eine Funktion schreiben, um die "Eltern" -Brille für jedes gegebene Glas zu erhalten.
Nun können wir uns einen Algorithmus überlegen, mit dem die in ein Glas gegossene Flüssigkeitsmenge unabhängig vom Überlauf aus diesem Glas ermittelt werden kann. Die Antwort ist jedoch, dass jedem Elternteil viel Flüssigkeit eingefüllt wird, abzüglich der Menge, die in jedem Elternglas gespeichert ist, geteilt durch 2. Summieren Sie dies einfach für alle Eltern. Schreiben Sie dies als Python-Fragment des Körpers einer amount_poured_into () -Funktion:
# p is coords of the current glass
amount_in = 0
for pp in parents(p):
amount_in += max((amount_poured_into(total, pp) - 1.0)/2, 0)
Mit max () soll sichergestellt werden, dass kein negativer Überlauf auftritt.
Wir sind fast fertig! Wir wählen ein Koordinatensystem mit 'y' auf der ganzen Seite, die erste Reihe ist 0, die zweite Reihe ist 1 usw. Die 'x'-Koordinaten haben eine Null unter der oberen Reihe und die zweite Reihe hat x-Koordinaten von -1 und +1, dritte Reihe -2, 0, +2 und so weiter. Der wichtige Punkt ist, dass das Glas ganz links oder ganz rechts in Stufe y abs (x) = y hat.
Wenn Sie das alles in Python (2.x) packen, haben wir:
def parents(p):
"""Get parents of glass at p"""
(x, y) = p
py = y - 1 # parent y
ppx = x + 1 # right parent x
pmx = x - 1 # left parent x
if abs(ppx) > py:
return ((pmx,py),)
if abs(pmx) > py:
return ((ppx,py),)
return ((pmx,py), (ppx,py))
def amount_poured_into(total, p):
"""Amount of fluid poured into glass 'p'"""
(x, y) = p
if y == 0: # ie, is this the top glass?
return total
amount_in = 0
for pp in parents(p):
amount_in += max((amount_poured_into(total, pp) - 1.0)/2, 0)
return amount_in
def amount_in(total, p):
"""Amount of fluid left in glass p"""
return min(amount_poured_into(total, p), 1)
Verwenden Sie also amount_in (total, p), um die tatsächliche Menge in einem Glas bei p zu erhalten.
Es ist nicht von der OP klar, aber das Bit über „Sie Parameter hinzufügen kippen“ bedeuten kann , die ursprüngliche Frage in Bezug auf dem Glas beantwortet werden muss Zahlen gezeigt. Dies wird gelöst, indem eine Zuordnungsfunktion von den Showglasnummern in das oben verwendete interne Koordinatensystem geschrieben wird. Es ist fummelig, aber es kann entweder eine iterative oder eine mathematische Lösung verwendet werden. Eine leicht verständliche iterative Funktion:
def p_from_n(n):
"""Get internal coords from glass 'number'"""
for (y, width) in enumerate(xrange(1, n+1)):
if n > width:
n -= width
else:
x = -y + 2*(n-1)
return (x, y)
Schreiben Sie jetzt einfach die Funktion amount_in () um, um eine Glaszahl zu akzeptieren:
def amount_in(total, n):
"""Amount of fluid left in glass number n"""
p = p_from_n(n)
return min(amount_poured_into(total, p), 1)