Puste szklanki wody są ułożone w następującej kolejności:
Gdy wlejesz płyn do 1. szklanki, jeśli jest pełna, dodatkowy płyn zostanie wlany do szklanek 2 i 3 w równych ilościach. Gdy szklanka 2 jest pełna, dodatkowa ciecz zostanie przelana do 4 i 5 i tak dalej.
Biorąc pod uwagę N litrów płynu, a maksymalna pojemność każdej szklanki wynosi 1 litr, podaj ilość płynu obecnego w dowolnej szklance, jeśli opróżnisz N litrów płynu, wlewając do szklanki wypełniając funkcję, getWaterInBucket(int N, int X)
gdzie X jest liczbą szklaną. Na przykład, jeśli chcę mieć 4 litry na początku i chcę znaleźć wodę w szklance 3, funkcja jestgetWaterInBucket(4, 3)
Jak rozwiązać to programowo? Próbowałem znaleźć rozwiązanie matematyczne, używając trójkąta Pascala. To nie zadziałało. Uznałem to za drzewo, więc mogę dodać taki parametr, getWaterInBucket(BTree root, int N, int X)
a następnie wypróbować rekurencyjne rozwiązanie dla każdego poziomu, ale parametry nie są dozwolone w tym problemie. Czy jest coś oczywistego, jakaś sztuczka?
źródło
Odpowiedzi:
Musisz tylko zasymulować nalewanie, coś w tym rodzaju
W tej chwili nie jest to drzewo. Ponieważ różne kieliszki wlewają się do tych samych kieliszków, co zapobiega temu, że jest drzewem.
źródło
return glasses[N-1]
, bo szklane liczby zaczynają się od 1 zamiast 0.Oto jak odpowiedziałbym na to pytanie w wywiadzie (nie widziałem tego pytania wcześniej i nie patrzyłem na inne odpowiedzi, dopóki nie znalazłem rozwiązania):
Najpierw próbowałem to rozgryźć (co nazywacie „rozwiązaniem matematycznym”), a kiedy dotarłem do szklanki 8, zdałem sobie sprawę, że będzie trudniej niż się wydawało, ponieważ szklanka 5 zaczyna przelewać się przed szklanką 4. W tym momencie ja postanowiłem pójść ścieżką rekurencyjną (tylko FYI, wiele pytań do wywiadu programowego wymaga rekurencji lub indukcji do rozwiązania).
Myśląc rekurencyjnie, problem staje się znacznie łatwiejszy: ile wody jest w szklance 8? Połowa kwoty, która wylała się z szklanek 4 i 5 (aż będzie pełna). Oczywiście oznacza to, że musimy odpowiedzieć, ile wylało się z okularów 4 i 5, ale okazuje się, że to też nie jest zbyt trudne. Ile wylało się ze szkła 5? Połowa z tego, co dużo, wylała się ze szklanek 2 i 3, minus litr, który pozostał w szklance 5.
Rozwiązanie tego całkowicie (i niechlujnie) daje:
W tym momencie (lub jak to pisałem) powiedziałbym ankieterowi, że nie jest to idealne rozwiązanie w produkcji: istnieje zduplikowany kod między
howMuchSpilledOutOf()
igetWaterInBucket()
; powinna istnieć centralna lokalizacja, która mapuje wiadra do ich „podajników”. Ale w wywiadzie, w którym szybkość i dokładność wdrożenia są ważniejsze niż szybkość wykonania i łatwość konserwacji (o ile nie wskazano inaczej), takie rozwiązanie jest lepsze. Następnie zaproponowałbym przeredagowanie kodu, aby był bliższy jakości, którą uważam za produkcyjną, i pozwoliłbym ankieterowi zdecydować.Ostatnia uwaga: jestem pewien, że mój kod gdzieś ma literówkę; Wspominam o tym również ankieterowi i mówię, że czułbym się bardziej pewny po refaktoryzacji lub testowaniu jednostkowym.
źródło
this isn't the ideal solution
.Myślenie o tym jak o problemie z drzewem to śledź czerwony, to tak naprawdę wykres kierunkowy. Ale zapomnij o tym wszystkim.
Pomyśl o szklance gdziekolwiek poniżej górnej. Będzie miał jedną lub dwie szklanki nad nim, które mogą się do niego przelać. Przy odpowiednim wyborze układu współrzędnych (nie martw się, patrz koniec) możemy napisać funkcję, aby uzyskać okulary „macierzyste” dla dowolnego szkła.
Teraz możemy pomyśleć o algorytmie, aby uzyskać ilość płynu wlewaną do szklanki, niezależnie od przelewu z tego szkła. Odpowiedź jest jednak taka, że do każdego rodzica wlewa się dużo płynu minus ilość przechowywana w każdym szkle rodzicielskim, podzielona przez 2. Wystarczy zsumować to dla wszystkich rodziców. Zapisanie tego jako fragmentu Pythona w treści funkcji quant_poured_into ():
Funkcja max () ma zapewnić, że nie wystąpi ujemna przepełnienie.
Jesteśmy prawie skończeni! Wybieramy układ współrzędnych z „y” w dół strony, szklanki pierwszego rzędu to 0, drugi rząd to 1 itd. Współrzędne „x” mają zero pod szkłem górnego rzędu, a drugi rząd ma współrzędne x -1 i +1, trzeci rząd -2, 0, +2 i tak dalej. Ważną kwestią jest to, że lewe lub prawe szkło na poziomie y będzie miało abs (x) = y.
Podsumowując wszystko w Pythonie (2.x), mamy:
Tak więc, aby uzyskać ilość faktycznie w szklance przy p, użyj kwoty_w (ogółem, p).
Z PO nie jest to jasne, ale fragment dotyczący „nie można dodać parametrów” może oznaczać, że na oryginalne pytanie należy odpowiedzieć pod względem wyświetlanych liczb szklanych . Rozwiązuje się to poprzez zapisanie funkcji mapowania z numerów szkieł pokazowych na wewnętrznym układzie współrzędnych stosowanym powyżej. To kłopotliwe, ale można zastosować iteracyjne lub matematyczne rozwiązanie. Łatwa do zrozumienia funkcja iteracyjna:
Teraz po prostu przepisz powyżej funkcję quant_in (), aby zaakceptować liczbę szklaną:
źródło
Ciekawy.
To wymaga podejścia symulacyjnego.
który drukuje (na 6 litrów):
co wydaje się być w porządku.
źródło
To jest funkcja dwumianowa. Stosunek wody między szklankami poziomu N można ustalić za pomocą nCr dla każdej szklanki na poziomie. Ponadto łączna liczba okularów przed poziomem N to suma od 1 do (N - 1), wzór, dla którego powinieneś być w stanie dość łatwo znaleźć. Tak więc, biorąc pod uwagę X, powinieneś być w stanie określić jego poziom i użyć nCr, aby sprawdzić proporcje szklanek dla tego poziomu, a tym samym określić, ile wody jest w X, jeśli i tak jest wystarczająca ilość litrów, aby zejść do X.
Po drugie, twój pomysł użycia BTree jest w porządku, po prostu BTree jest zmienną wewnętrzną, a nie parametrem zewnętrznym.
IOW, jeśli omawiałeś tę matematykę w swojej edukacji (tutaj w Wielkiej Brytanii uczy się jej przed uniwersytetem), powinieneś być w stanie rozwiązać to bez większego problemu.
źródło