Якщо думати про це як про проблему дерева - це червоношкіра оселедець, це дійсно спрямований графік. Але забудьте про все це.
Подумайте склянку де-небудь нижче верхнього. Буде над ним один-два склянки, які можуть переливатися в нього. За допомогою відповідного вибору системи координат (не хвилюйтеся, див. Кінець), ми можемо написати функцію, щоб отримати «батьківські» окуляри для будь-якого скла.
Тепер ми можемо продумати алгоритм отримання кількості рідини, вилитої у склянку, незалежно від переливу з цієї склянки. Відповідь, однак, скільки рідини виливається в кожного з батьків, за вирахуванням кількості, що зберігається в кожній батьківській склянці, ділиться на 2. Просто підсумуйте, що для всіх батьків. Записавши це як фрагмент пітона на тіло функції суму_пур_інто ():
# 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)
Макс () призначений для того, щоб ми не отримали негативну кількість переповнення.
Ми майже закінчили! Ми вибираємо систему координат з «у» вниз на сторінці, окуляри першого ряду дорівнюють 0, другий рядок - 1 і т. Д. Координати 'x' мають нуль під склом верхнього ряду, а другий ряд має x координати -1 і +1, третій ряд -2, 0, +2 тощо. Важливим моментом є те, що в лівій або правій частині склянки у рівні y буде abs (x) = y.
Згорнувши все це в python (2.x), ми маємо:
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)
Отже, щоб отримати фактично суму в склянці на р, використовуйте суму_in (всього, p).
З ОП це не зрозуміло, але біт про "ти не можеш додати параметри" може означати, що на оригінальне запитання потрібно відповісти з точки зору показаних скляних чисел . Це вирішується шляхом запису функції відображення від показових номерів скла до внутрішньої системи координат, що використовується вище. Це химерно, але можна використовувати або ітераційне, або математичне рішення. Легка для розуміння ітеративна функція:
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)
Тепер просто перепишіть функцію суму_in (), щоб прийняти номер скла:
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)