Pensando en esto como un problema de árbol es una pista falsa, es realmente un gráfico dirigido. Pero olvídate de eso.
Piense en un vaso en cualquier lugar debajo del superior. Tendrá uno o dos vasos encima que pueden desbordarse. Con la elección adecuada del sistema de coordenadas (no se preocupe, vea el final) podemos escribir una función para obtener las gafas "principales" para cualquier vidrio dado.
Ahora podemos pensar en un algoritmo para obtener la cantidad de líquido vertido en un vaso, independientemente del desbordamiento de ese vaso. Sin embargo, la respuesta es que se vierte mucho líquido en cada padre menos la cantidad almacenada en cada vaso padre, dividido por 2. Simplemente suma eso para todos los padres. Escribiendo esto como un fragmento de Python del cuerpo de una función 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)
El máximo () es para garantizar que no tengamos una cantidad negativa de desbordamiento.
¡Ya casi terminamos! Elegimos un sistema de coordenadas con 'y' hacia abajo de la página, los cristales de la primera fila son 0, la segunda fila es 1, etc. Las coordenadas 'x' tienen un cero debajo del cristal de la fila superior y la segunda fila tiene coordenadas x de -1 y +1, tercera fila -2, 0, +2, y así sucesivamente. El punto importante es que el vidrio más a la izquierda o a la derecha en el nivel y tendrá abs (x) = y.
Envolviendo todo eso en python (2.x), tenemos:
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)
Entonces, para obtener la cantidad realmente en un vaso en p, use cantidad_in (total, p).
No está claro en el OP, pero el bit sobre "no puede agregar parámetros" puede significar que la pregunta original debe responderse en términos de los números de vidrio que se muestran. Esto se resuelve escribiendo una función de mapeo a partir de los números de vidrio de muestra en el sistema de coordenadas interno utilizado anteriormente. Es complicado, pero se puede usar una solución iterativa o matemática. Una función iterativa fácil de entender:
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)
Ahora solo reescriba la función cantidad_in () anterior para aceptar un número de vidrio:
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)