Ostatnio w Puzzling.SE napotkałem problem związany z określeniem, które dwie butelki z większej liczby są zatrute, gdy trucizna aktywuje się tylko wtedy, gdy oba składniki są pijane. Skończyło się to dość ciężką próbą, a większość ludzi zdołała sprowadzić go do 18 lub 19 więźniów przy użyciu zupełnie innych algorytmów.
Oryginalna deklaracja problemu jest następująca:
Jesteś władcą średniowiecznego królestwa, który uwielbia organizować przyjęcia. Dworzanin, który ostatni raz próbował otruć jedną z twoich butelek wina, był wściekły, gdy dowiedział się, że udało ci się zidentyfikować, którą butelkę zatruł na 1000 z zaledwie dziesięcioma więźniami.
Tym razem jest trochę bardziej sprytny. Opracował złożoną truciznę
P: podwójny płyn, który jest śmiertelny tylko wtedy, gdy zmieszają się dwa indywidualnie nieszkodliwe składniki; jest to podobne do działania żywicy epoksydowej. Wysłał ci kolejną skrzynię 1000 butelek wina. Jedna butelka ma składnik,C_aa druga ma składnikC_b. (P = C_a + C_b)Każdy, kto pije oba składniki, umrze po północy w noc, w której wypił ostatni składnik, niezależnie od tego, kiedy w ciągu dnia wchłonął płyn. Każdy składnik trucizny pozostaje w ciele, dopóki drugi składnik nie zostanie aktywowany, więc jeśli wypijesz jeden składnik jednego dnia, a drugi następnego, umrzesz o północy pod koniec drugiego dnia.
Masz dwa dni do następnej imprezy. Jaka jest minimalna liczba więźniów, których należy użyć do testowania, aby zidentyfikować, które dwie butelki są skażone, i jakiego algorytmu należy przestrzegać przy tej liczbie więźniów?
Premia
Dodatkowo, przypuśćmy, że dysponowałeś stałym limitem 20 więźniów, jaka jest maksymalna liczba butelek, które możesz teoretycznie przetestować i dojść do dokładnego wniosku, na które butelki miało to wpływ?
Twoim zadaniem jest zbudowanie programu do rozwiązania problemu bonusowego. Biorąc pod uwagę nwięźniów, twój program opracuje harmonogram testów, który będzie w stanie wykryć dwie zatrute butelki wśród mbutelek, gdzie msą one tak duże, jak to możliwe.
Twój program początkowo przyjmie jako dane wejściowe liczbę N, liczbę więźniów. Następnie wyświetli:
M, liczba butelek, które spróbujesz przetestować. Te butelki będą oznaczone od1doM.Nlinie zawierające etykiety butelek, które wypije każdy więzień.
Twój program pobierze następnie dane wejściowe, którzy więźniowie zmarli pierwszego dnia, z więźniem w pierwszej linii 1, w kolejnej linii 2itd. Następnie wyświetli:
Nwięcej linii, zawierających etykiety butelek, które każdy więzień wypije. Martwi więźniowie będą mieli puste linie.
Twój program następnie weźmie pod uwagę, którzy więźniowie zmarli drugiego dnia, i wyśle dwie liczby, Ai Breprezentując, które dwie butelki twój program uważa za truciznę.
Przykładem wejście dla dwóch więźniów i cztery butelki może iść jako takie, czy butelek 1i 3są zatrute:
> 2 // INPUT: 2 prisoners
4 // OUTPUT: 4 bottles
1 2 3 // OUTPUT: prisoner 1 will drink 1, 2, 3
1 4 // OUTPUT: prisoner 2 will drink 1, 4
> 1 // INPUT: only the first prisoner died
// OUTPUT: prisoner 1 is dead, he can't drink any more bottles
3 // OUTPUT: prisoner 2 drinks bottle 3
> 2 // INPUT: prisoner 2 died
1 3 // OUTPUT: therefore, the poisoned bottles are 1 and 3.
The above algorithm may not actually work in all
cases; it's just an example of input and output.
Harmonogram testów Twojego programu musi z powodzeniem określać każdą możliwą parę zatrutych butelek, aby mogła być ważna.
Twój program będzie oceniany według następujących kryteriów, w kolejności:
Maksymalna liczba butelek, jaką może rozpoznać dla skrzynki
N = 20.Liczba butelek w skrzynce
N = 21, a następnie kolejne skrzynie.Długość kodu. (Wygrywa krótszy kod).