Bunu bir ağaç problemi olarak düşünmek kırmızı bir ringa balığıdır, gerçekten yönlendirilmiş bir grafiktir. Ama bütün bunları unut.
Üstünün altında bir yerde bir bardak düşünün. Üzerine taşabilecek bir veya iki bardağı olacaktır. Uygun koordinat sistemi seçimi ile (endişelenmeyin, sonuna bakın) herhangi bir cam için "ana" gözlükleri elde etmek için bir fonksiyon yazabiliriz.
Şimdi, o bardaktan taşma durumundan bağımsız olarak, bir bardağa dökülen sıvı miktarını elde etmek için bir algoritma düşünebiliriz. Bunun cevabı, her bir ebeveynin camına depolanan miktarı eksi 2'ye bölerek çok fazla sıvı akmasıdır. Bunları sadece tüm ebeveynler için toplayın. Bunu bir miktar_poured_into () fonksiyonunun gövdesinin piton parçası olarak yazmak:
# 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)
Maksimum (), negatif bir taşma miktarı almadığımızdan emin olmak içindir.
Neredeyse bitti! Sayfada 'y' aşağı, birinci sıra gözlük 0, ikinci sıra 1 vb. Olan bir koordinat sistemi seçiyoruz. 'X' koordinatları üst sıra camın altında sıfır, ikinci sıra -1 ve +1, üçüncü satır -2, 0, +2 vb. Önemli olan nokta, y seviyesindeki en sol veya sağ camın abs (x) = y olacağıdır.
Bunların hepsini python (2.x) içine sarmak, biz:
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)
Bu yüzden miktarı p deki bir bardağa almak için, miktar_ini (toplam, p) kullanın.
OP'den net değil, ancak “parametre ekleyemezsiniz” biti, orijinal sorunun gösterilen cam sayılarıyla cevaplanması gerektiği anlamına gelebilir . Bu, gösteri camı numaralarından yukarıda kullanılan dahili koordinat sistemine bir haritalama işlevi yazılarak çözülür. Fiddly, ancak yinelemeli veya matematiksel bir çözüm kullanılabilir. Anlaşılması kolay, yinelemeli işlev:
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)
Şimdi, bir cam sayısını kabul etmek için yukarıdaki miktar_in () işlevini yeniden yazmanız yeterlidir:
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)