Penser à cela comme un problème d'arbre est un redingue, c'est vraiment un graphique dirigé. Mais oubliez tout ça.
Pensez à un verre n'importe où sous celui du haut. Il aura un ou deux verres au-dessus qui peuvent déborder. Avec le choix approprié du système de coordonnées (ne vous inquiétez pas, voir la fin), nous pouvons écrire une fonction pour obtenir les verres "parents" pour n'importe quel verre donné.
Maintenant, nous pouvons penser à un algorithme pour obtenir la quantité de liquide versée dans un verre, indépendamment du débordement de ce verre. La réponse est cependant que beaucoup de liquide est versé dans chaque parent moins la quantité stockée dans chaque verre parent, divisée par 2. Additionnez cela pour tous les parents. L'écriture en tant que fragment python du corps d'une fonction amount_poured_into ():
# 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)
Le max () est de s'assurer que nous n'obtenons pas une quantité négative de débordement.
Nous avons presque fini! Nous choisissons un système de coordonnées avec «y» en bas de la page, les verres de la première rangée sont 0, la deuxième rangée est 1, etc. Les coordonnées «x» ont un zéro sous le verre de la rangée supérieure et la deuxième rangée a les coordonnées x de -1 et +1, troisième ligne -2, 0, +2, etc. Le point important est que le verre le plus à gauche ou à droite du niveau y aura abs (x) = y.
Enveloppant tout cela en python (2.x), nous avons:
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)
Donc, pour obtenir la quantité réellement dans un verre à p, utilisez amount_in (total, p).
Ce n'est pas clair à partir de l'OP, mais le peu de "vous ne pouvez pas ajouter de paramètres" peut signifier que la question d'origine doit être répondue en termes de numéros de verre affichés. Ceci est résolu en écrivant une fonction de mappage des numéros de verre d'exposition au système de coordonnées interne utilisé ci-dessus. C'est compliqué, mais une solution itérative ou mathématique peut être utilisée. Une fonction itérative facile à comprendre:
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)
Maintenant, réécrivez simplement la fonction amount_in () ci-dessus pour accepter un numéro de verre:
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)