Adam Borowski (treść)    Marcin Sawicki (opracowanie)    Tomasz Waleń (program wzorcowy)

Paski

Paski to gra dwuosobowa. Rekwizytami potrzebnymi do gry są paski w trzech kolorach: czerwonym, zielonym i niebieskim. Wszystkie paski czerwone mają wymiary ctimes 1, zielone ztimes 1, a niebieskie ntimes 1, gdzie c, z i n są liczbami naturalnymi. Gracze dysponują nieograniczoną pulą pasków każdego koloru (jeśli pewnych pasków zabraknie, to zawsze można dodrukować).

Plansza do gry jest prostokątem o wymiarach ptimes 1 i składa się z p pól o wymiarach 1times 1.

Gracze wykonują ruchy na przemian. Ruch polega na ułożeniu na planszy paska dowolnego koloru. Obowiązują przy tym następujące zasady:

Przegrywa gracz, który jako pierwszy nie może wykonać ruchu zgodnie z zasadami gry. Pierwszy gracz to gracz, który wykonuje pierwszy ruch w grze. Mówimy, że pierwszy gracz ma strategię wygrywającą, jeżeli niezależnie od posunięć drugiego gracza zawsze może wygrać.

Zadanie

Napisz program, który:

Wejście

Pierwszy wiersz zbioru wejściowego PAS.IN zawiera trzy liczby naturalne c, z i n, 1leq c,n,zleq 1000, równe długościom pasków, odpowiednio, czerwonych, zielonych i niebieskich. Liczby w wierszu są poodzielane pojedynczymi znakami odstępu.

Drugi wiersz pliku PAS.IN zawiera jedną liczbę m, 1leq mleq 1000, równą liczbie różnych plansz do rozpatrzenia.

Wiersze od 3 to m+2 zawierają po jednej liczbie p, 1leq pleq 1000. Liczba w wierszu i+2 jest długością i-tej planszy.

Wyjście

Plik wyjściowy PAS.OUT powinien zawierać m wierszy. W i-tym wierszu pliku powinna być zapisana jedna liczba:

Przykład

Dla pliku wejściowego PAS.IN
1 5 1
3
1
5
6
poprawną odpowiedzią jest plik wyjściowy PAS.OUT
1
1
2

Rozwiązanie

W teorii gier istnieje pojęcie gry zamkniętej. Gry, które polegają na kolejnych jawnych posunięciach dwu graczy (np. gra w paski, a także szachy, warcaby, kółko i krzyżyk, wilk i owce itd.) są przykładami gier zamkniętych. Znane twierdzenie mówi, że wszystkie takie gry są niesprawiedliwe lub czcze, tzn. że zawsze albo jeden z graczy ma strategię wygrywającą, albo obaj gracze mogą co najwyżej wymusić remis lub nieskończoną rozgrywkę.

Gra w paski jest ponadto grą kategoryczną, czyli zawsze kończy się wygraną jednego z graczy. Jest zatem niesprawiedliwa: któryś z graczy musi mieć strategię prowadzącą do zwycięstwa.

Będąc młodym informatykiem, z pewnością zdajesz sobie sprawę, Szanowny Czytelniku, że teoretycznie można znajdować strategie wygrywające poprzez przeszukiwanie drzewa gry, i że chyba dla żadnej rozsądnej gry nie jest to wykonalne w praktyce. Można polemizować, czy paski są rozsądną grą, w każdym razie przeszukiwanie całego drzewa jest w tym wypadku zbyt pracochłonne.

Ruch w grze w paski można jednak postrzegać jako rozbicie planszy na mniejsze kawałki. Podsuwa nam to pomysł skorzystania z metod programowania dynamicznego. Jeśli umielibyśmy powiedzieć coś o tych "mniejszych kawałkach", to być może umielibyśmy również sklasyfikować jakoś wyjściową planszę?

Chwila namysłu pozwala stwierdzić, że nie wystarczy informacja, który z graczy ma strategię wygrywającą na każdym z kawałków planszy, by ustalić, kto ją ma na całej planszy. Potrzebujemy zatem subtelniejszego rozróżnienia pomiędzy planszami, jednak takiego, z którego łatwo wynika, kto na danej planszy zwycięży. Jakiego? O tym już za chwilę...

Skąd ten XOR?

Szanowny Czytelniku! Być może poznałeś już program wzorcowy i wiesz, że w magiczny sposób korzysta on z właściwości operacji XOR. W tym artykule postaram się przekonać Cię, że w rozwiązaniu tym nie ma aż tak wiele magii. Użyję języka teorii grup, co w wielu miejscach uprości opis. Mimo wszystko, zajmie to jednak trochę czasu, a skoro Ty oglądałeś już rozwiązanie wzorcowe, to pewnie nie należysz do cierpliwych. Dlatego już teraz przedstawię główną myśl rozwiązania. Oto ona:

W grze w paski, jeśli w jakiejś chwili plansza daje się podzielić na dwa identyczne fragmenty, to wiadomo, że gracz, na którego przypada kolejka, musi przegrać: drugi gracz będzie powtarzał jego ruchy, tyle że symetrycznie, na drugim z identycznych fragmentów planszy. Jeśli pierwszy gracz może jeszcze wykonać ruch, to również i drugi może po nim wykonać ruch symetryczny. A jeśli pierwszy nie może, to przegrał!

Ta cecha gry w paski jest w pełni analogiczna do znanej właściwości operacji XOR, polegającej na tym, że dla dowolnej liczby k mamy k rm XOR k =0. Liczba k odpowiada jednemu z dwu identycznych egzemplarzy planszy, zaś 0 oznacza porażkę pierwszego gracza.

Oczywiście jest to tylko intuicja. Dlatego zachęcam nawet Ciebie, Niecierpliwy Czytelniku, do dalszej lektury.

Terminologia

Na początku gry plansza jest pojedynczym prostokątem zbudowanym z ptimes1 kwadratowych pól. Kolejne ruchy polegają na zakrywaniu fragmentów planszy. Pola zakryte nie biorą dalej udziału w grze. Natomiast pola wolne po każdym ruchu tworzą pewien układ spójnych prostokątów. Przykładowo, na rysunku 1 widzimy początek pewnej rozgrywki na planszy długości 24. Po pierwszym ruchu wolne pola tworzą układ dwu prostokątów o długościach 10 i 6, a po następnym mamy trzy prostokąty o długościach 3, 3 i 6.

Definicja. Spójny prostokąt, zbudowany z wolnych pól, do którego skrajów przylegają pola zajęte lub brzegi planszy (czyli nie dający się powiększyć o kolejne wolne pola bez naruszania spójności), nazywać będziemy obszarem. Każdy układ obszarów (również początkowy, czyli zbudowany z jednego obszaru ptimes 1) będziemy nazywać planszą.

Rys. 1. W trakcie rozgrywki plansza rozpada się na coraz mniejsze obszary

  epsffilepaski1.eps

Zwróćmy uwagę, że z punktu widzenia strategii rozgrywki (w szczególności tego, kto wygra), nie ma znaczenia kolejność, w jakiej na danej planszy występują poszczególne obszary. Czyli plansze 3, 3, 6 oraz 3, 6, 3 możemy uważać za jednakowe. Dlatego odpowiednim pojęciem matematycznym do reprezentowania plansz będzie multizbiór, którego elementami będą liczby całkowite dodatnie - długości poszczególnych obszarów.

Definicja. Multizbiór jest to zbiór par (x,n), gdzie x jest elementem multizbioru, zaś n=1,2,3,... jest liczbą całkowitą dodatnią, określającą w ilu egzemplarzach dany element należy do multizbioru. Oczywiście dla każdego x do multizbioru może należeć co najwyżej jedna para postaci (x,n). Operacje sumy i części wspólnej są dla multizbiorów zdefiniowane w sposób naturalny. Na przykład, jeśli A=(a,3),(b,1),(c,1), zaś B=(a,2),(b,3),(d,5), to Acup B=(a,5),(b,4),(c,1),(d,5... oraz Acap B=(a,2),(b,1).

Plansze przedstawimy jako multizbiory długości tworzących je obszarów. Przykładowo, przedstawieniem planszy 3, 3, 6, jak również planszy 3, 6, 3, jest ten sam multizbiór (3,2),(6,1). W dalszych rozważaniach potrzebna nam będzie operacja łączenia dwu plansz, czyli budowania planszy, składającej się ze wszystkich obszarów, wchodzących w skład obu plansz. Operacji łączenia plansz dokładnie odpowiada suma multizbiorów.

Odrobina abstrakcji

Rozważamy grę rozpoczynającą się od planszy ptimes 1 i prowadzoną przy użyciu pasków o długościach c, z i n. W każdym stanie gry plansza będzie zatem zbudowana z obszarów o długościach leq p. Oczywiście, nie każda plansza zbudowana z takich obszarów może się pojawić w naszej rozgrywce, w szczególności suma długości obszarów nigdy nie przekroczy p.

Na nasze potrzeby wygodnie jednak będzie o tym zapomnieć i zbadać zbiór X wszystkich plansz, zbudowanych ze skończonej liczby obszarów, z których każdy ma długość leq p. Zatem X jest rodziną skończonych multizbiorów, których elementy są liczbami od 1 do p. Dzięki temu, w zbiorze X wykonalne jest działanie łączenia plansz (czyli dodawania multizbiorów) - to znaczy, że plansza uzyskana przez połączenie dwu elementów zbioru X również należy do tego zbioru. Zwróćmy uwagę, że w zbiorze X znajduje się również plansza pusta, czyli pusty multizbiór (odpowiada ona całkowitemu wypełnieniu planszy paskami). Oznaczmy ją przez emptyset. Dla dowolnego xin X mamy oczywiście xcup emptyset = x, czyli emptyset jest elementem neutralnym dla działania łączenia plansz. Nadto łączenie plansz jest, jak każdy widzi, przemienne i (jak sama nazwa wskazuje) łączne.

Definicja. Zbiór Y z działaniem dwuargumentowym + nazywamy grupą przemienną albo abelową, jeśli spełnia on następujące warunki:

Pojęcie grupy przemiennej powinno być dobrze znane każdemu: najprostsze przykłady to liczby całkowite (lub wymierne, lub rzeczywiste) z dodawaniem (w tym kontekście mówi się raczej o elemencie przeciwnym, a nie odwrotnym), liczby wymierne (lub rzeczywiste) bez zera z mnożeniem, wektory na płaszczyźnie z dodawaniem wektorów, itd.

Widzimy, że zbiór X z działaniem cup spełnia wszystkie warunki oprócz odwracania. Przypomnijmy sobie jednak, że na planszy, dającej się podzielić na dwa identyczne fragmenty gracz, na którego przypada kolejka, musi przegrać, tak samo jak na planszy emptyset. Z punktu widzenia strategii można więc uważać, że plansza postaci xcup x jest równoważna planszy emptyset. Postaramy się zatem tak przerobić zbiór X z działaniem cup, by każdy jego element był odwrotny sam do siebie. Z grubsza biorąc, utożsamimy elementy postaci xcup x z emptyset. Znów będzie nam potrzebna

Definicja. Relacja dwuargumentowa sim na zbiorze Y jest relacją równoważności, jeśli jest

Relacje równoważności są matematycznym sposobem na utożsamienie pewnych elementów zbioru: każda relacja równoważności na zbiorze Y jednoznacznie zadaje jego podział, czyli rodzinę cal A podzbiorów zbioru Y taką, że y_1sim y_2 wtedy i tylko wtedy, gdy dla pewnego elementu B rodziny cal A zachodzi jednocześnie y_1in B oraz y_2in B. Taką rodzinę oznacza się przez ^Y/_sim = cal A. Każdy element yin Y należy do dokładnie jednego elementu Bin^Y/_sim; ten jedyny element oznaczamy [y]=B i nazywamy klasą abstrakcji elementu y. Oczywiście [y_1]=[y_2] wtedy i tylko wtedy, gdy y_1sim y_2. Czyli [y]subseteq Y jest zbiorem tych i tylko tych elementów zbioru Y, które właśnie utożsamiliśmy z y za pomocą relacji sim.

Dobrym pomysłem okazuje się następujące określenie naszej relacji: x_1equiv x_2 wtedy i tylko wtedy, gdy na planszy x_1cup x_2 gracz rozpoczynający musi przegrać (tzn. jego przeciwnik posiada strategię wygrywającą). Wiemy zatem, że zawsze xequiv x. Poza tym jest oczywiście wiele innych par x_1, x_2 takich, że x_1equiv x_2 - jak się niedługo okaże, działa to na naszą korzyść. Przypominam, że rozmiary pasków c, z, n są cały czas ustalone. Dla innych rozmiarów pasków możemy otrzymać zupełnie inną relację!

Z drugiej strony, uważny Czytelnik niedługo już zorientuje się, że utożsamianie plansz, na których gracz rozpoczynający ma strategię wygrywającą, byłoby dużo gorszym pomysłem. Poza bardzo prostymi przypadkami, musielibyśmy wówczas w trosce o przechodniość naszej relacji konsekwentnie posklejać ze sobą wszystko.

Zadanie dla czytelnika. Proszę sprawdzić, że equiv jest istotnie relacją równoważności (spełnia definicję). Wskazówka: aby udowodnić przechodniość, należy, znając strategię wygrywającą drugiego gracza dla plansz x_1cup x_2 oraz x_2cup x_3, opisać sposób (algorytm) gry dla drugiego gracza, który zagwarantuje mu zwycięstwo na planszy x_1cup x_3.

Zagadka tylko dla wtajemniczonych: czy jeśli zdefiniowalibyśmy simeq jako najmniejszą relację równoważności na X, która utożsamia wszystkie plansze postaci xcup x z emptyset, to czy equiv=simeq? A gdyby dodatkowo zarządać, by simeq było najmniejszą kongruencją na X ze względu na cup?

No dobrze, powiecie, utożsamiliśmy jakieś elementy, ale przecież działanie cup było określone na X, a my mamy teraz inny zbiór ^X/_equiv. A jednak wszystko jest pod kontrolą! Przypomnijmy tylko jedno pojęcie, z którym każdy spotkał się (lub spotka) w szkole:

Definicja. Relacja równoważności sim jest kongruencją na zbiorze Y ze względu na działanie +, jeśli dla dowolnych y_1, y'_1,y_2,y'_2in Y jeśli tylko y_1sim y'_1 oraz y_2sim y'_2, to zachodzi również y_1+y_2sim y'_1+y'_2.

Przypadek "szkolny" to relacja przystawania modulo n, która utożsamia liczby całkowite a,bin bf Z wtedy i tylko wtedy, gdy a-b dzieli się przez n. Jest to relacja równoważności, co więcej jest to kongruencja ze względu na dodawanie, odejmowanie i mnożenie.

Kongruencja pozwala wykonywać działania w zbiorze klas abstrakcji ^Y/_sim: aby np. dodać dwie klasy, bierzemy dowolną parę ich elementów i dodajemy, a następnie znajdujemy klasę abstrakcji sumy. To, że relacja jest kongruencją, nie oznacza nic więcej, niż że tak zdefiniowane działanie jest dobrze określone w zbiorze ^Y/_sim, tzn. że różne wybory reprezentantów prowadzą w wyniku do tej samej klasy abstrakcji.

Na całe szczęście, equiv jest kongruencją w X ze względu na cup. Proszę to sprawdzić wprost z definicji, dowód będzie podobny do dowodu faktu, że relacja equiv jest przechodnia.

Mamy zatem

Fakt. ^X/_equiv z działaniem zadanym przez cup jest grupą przemienną, z elementem neutralnym [emptyset] (klasa abstrakcji zbioru pustego). Działanie w tej grupie również będziemy oznaczać cup, zaś element neutralny po prostu przez 0=[emptyset].

Istotnie, podzielenie X przez equiv nie mogło popsuć łączności, ani przemienności cup, ani neutralności emptyset (która przeniosła się na całą klasę abstrakcji [emptyset]), i oczywiście uzyskaliśmy elementy odwrotne: każdy element jest odwrotny sam do siebie.

Do czego była nam potrzebna ta "odrobina" abstrakcji?

Potrzeba wyjaśnić, czemu miał służyć ten długi ciąg definicji. Celów było kilka. Po pierwsze, możemy teraz zwięźle sformułować nasz cel: algorytm ma stwierdzać, czy dla danej planszy x, składającej się z jednego obszaru długości p, zachodzi xequivemptyset, czyli czy [x]=0 (gdyż zgodnie z naszą definicją, xequivemptyset wtedy i tylko wtedy, gdy drugi gracz ma strategię wygrywającą na planszy xcupemptyset=x).

Po drugie, bez określenia naszej grupy langle^X/_equiv,cup,0rangle wiele faktów, które w tej chwili są dla nas najzupełniej oczywiste, należałoby za każdym razem dowodzić "ręcznie" w sposób podobny do dowodu przechodniości relacji equiv (a więc byłyby one pozostawione jako zadania dla Ciebie, Szanowny Czytelniku). Przykład takiego faktu: jeśli na planszy x strategię wygrywającą ma drugi gracz (w szczególności, jeśli np. x=x'cup x'), to na planszy x_1cup x strategię wygrywającą ma ten sam gracz, co na planszy x1. Uzasadnienie: [x]=0, więc [x_1]cup[x]=[x_1]. Własności grup pozwalają nam wycisnąć wszystko co się da z przeprowadzonych już przez Ciebie dowodów, że equiv jest relacją równoważności i kongruencją ze względu na cup.

Po trzecie i najważniejsze, jak się za chwilę okaże, klasy abstrakcji naszej relacji dają się efektywnie obliczać metodą programowania dynamicznego.

Trochę porządków

Na drodze do rozwiązania czeka nas jeszcze jedno niespodziewane odkrycie: klasy plansz (czyli klasy abstrakcji relacji equiv) dają się uporządkować!

Zauważmy najpierw, że dla dowolnej planszy x, jeśli [x]not=0, to z planszy x można jednym ruchem dojść do pewnej planszy x_0in0=[emptyset]. Innymi słowy, z każdej planszy x wygrywającej dla gracza, na którego przypada kolejka, można zawsze jednym ruchem przejść do jakiejś planszy x0 przegrywającej dla gracza, którego kolejka wypadnie po tym ruchu (a więc który będzie musiał położyć pierwszy pasek na planszy x0). Jest to ten właśnie ruch, który graczowi rozpoczynającemu grę na planszy x gwarantuje zwycięstwo. Oczywiście, na planszy x być może da się wykonać wiele innych ruchów, które mogą prowadzić do plansz z innych klas. Ważne jest jednak istnienie co najmniej jednego wygrywającego posunięcia dla każdej spośród plansz z klasy [x]not=0.

Wykorzystajmy konsekwentnie tę obserwację i określmy relację dwuargumentową succ na zbiorze ^X/_equiv jak następuje: dla klas B_1,B_2in^X/_equiv zachodzi B_1succ B_2 wtedy i tylko wtedy, gdy z każdej planszy x_1in B_1 można jednym ruchem dojść do pewnej planszy x_2in B_2.

Na razie wiemy tylko, że dla [x]=Bnot=0 jest Bsucc0. Nie wiemy ani czy może zajść 0succ B dla jakiegoś B, ani czy może być B_1succ B_2 dla jakichkolwiek B_1,B_2not=0.

Fakt 1. (najważniejszy) Jeśli B_1,B_2in ^X/_equiv i B_1not=B_2, to albo B_1succ B_2, albo B_2succ B_1.

Dowód. Niech nie zachodzi ani B_1succ B_2, ani B_2succ B_1. Czyli istnieje plansza x_1in B_1, z której jednym ruchem nie da się dojść do żadnej spośród plansz z klasy B2. Analogicznie, istnieje pewna plansza x_2in B_2, na której żadne posunięcie nie prowadzi do klasy B1. Rozważmy planszę x_1cup x_2. Jeśli gracz, na którego przypada kolejność, wykona na tej połączonej planszy ruch w obrębie części x1, to przejdzie do pewnej planszy x'_1cup x_2, gdzie x'_1notin B_2. A zatem [x'_1]not=[x_2]. Do tej nierówności dodajmy stronami [x_2], otrzymamy [x'_1]cup[x_2]not=[x_2]cup[x_2..., czyli [x'_1cup x_2]not=0. Jest to zatem ruch prowadzący do porażki. Gracz przegra również, jeśli położy pasek w obrębie planszy x2. Czyli plansza x_1cup x_2 jest dla niego przegrywająca, to znaczy [x_1cup x_2]=0, skąd B_1=B_2, co kończy dowód.

Fakt 2. Dla żadnego Bin^X/_equiv nie zachodzi Bsucc B.

Dowód. Jeśli by tak było, to startując od dowolnej planszy x_1in B moglibyśmy wykonać ruch, prowadzący do pewnej planszy x_2in B, następnie jednym ruchem przeszlibyśmy do planszy x_3in B i tak w nieskończoność. A nie jest to możliwe, bo po każdym ruchu liczba wolnych pól zmniejsza się co najmniej o długość najkrótszego z pasków c, z, n!

Fakt 3. Dla żadnych B_1,B_2in^X/_equiv nie zachodzi jednocześnie B_1succ B_2 i B_2succ B_1.

Dowód. Podobnie jak poprzednio, prowadziłoby to do istnienia nieskończonej rozgrywki, w której na zmianę przechodzilibyśmy z planszy z klasy B1 do planszy z klasy B2 i z powrotem.

Fakt 4. Jeśli B_1succ B_2 oraz B_2succ B_3, to B_1succ B_3.

Dowód. Ten fakt jest chyba dość zaskakujący, gdyż oznacza, że z planszy z klasy B1 do planszy z klasy B3 można zawsze przejść jednym ruchem, a nie dwoma (choć oczywiście dwoma też się da). Uzasadnienie jest jednak proste: nie może oczywiście być B_1=B_3 (wykluczyliśmy to przed chwilą). Musi być zatem B_3succ B_1 lub B_1succ B_3. Jednak w tym pierwszym przypadku znów znaleźlibyśmy nieskończoną rozgrywkę, prowadzącą kolejno z klasy B1 do B2, z B2 do B3, a z B3 na powrót do B1 i tak w kółko. Pozostaje jedyna możliwość B_1succ B_3.

Fakt 5. Klas plansz w X jest skończenie wiele.

Dowód. (Pamiętamy, że sam zbiór X był nieskończony.) Niech xm oznacza planszę, zbudowaną z jednego obszaru długości m (czyli x_m=(m,1)), gdzie 1leq mleq p. Wówczas oczywiście każda plansza xin X daje się przedstawić jako suma

x=underbracex_1cup x_1cupldot...

Oczywiście dopuszczamy, by dla pewnych k było n_k=0. Planszę x reprezentuje multizbiór (1,n_1),ldots,(p,n_p), trzeba tylko pominąć te pary (k, n_k), dla których n_k=0.

Aby znaleźć klasę planszy x zauważmy, że underbrace[x_m]cup ldotscup [... jest równe [x_m] dla nm nieparzystego, zaś 0 dla nm parzystego. Suma ta upraszcza się zatem do co najwyżej jednego składnika. W związku z tym, mamy

[x]=B_1cup B_2cupldotscup B_p

gdzie odpowiednio B_m=[x_m] lub B_m=0, zależnie od parzystości liczby nm. Sum tej postaci jest zaś tylko skończona liczba, dokładnie 2p.

Zwróćmy uwagę, że klas plansz może nie być dokładnie 2p, tylko mniej, gdyż może się np. zdarzyć, że dla pewnych m'not= m jest [x_m']=[x_m. Np. jeśli c,z,ngeq 3, to oczywiście 0=[x_1]=[x_2].

Wniosek z faktów 1-5: Klasy plansz można ponumerować kolejnymi liczbami naturalnymi tak, by klasa 0 miała numer 0 i by dla dowolnych dwóch klas B',B" numer klasy B' był większy od numeru klasy B" wtedy i tylko wtedy, gdy B'succ B.

Na podstawie udowodnionych faktów wniosek ten powinien wydawać się oczywisty. Takie własności może po prostu mieć tylko naturalny porządek na liczbach naturalnych 0<1<2...<l-1<l. Jako zadanie proponuję uważnie uzasadnić ten wniosek np. przez indukcję lub posiłkując się pojęciami "dagu" (acyklicznego grafu skierowanego) i sortowania topologicznego. Klasę o numerze j będziemy od teraz oznaczać Bj. W szczególności, 0=B^0.

Programowanie dynamiczne

Najwyższa pora przejść do opisu algorytmu. Przypominam, że naszym celem jest obliczanie klas poszczególnych plansz.

Na podstawie wyciągniętego przed chwilą wniosku wiemy, że z każdej planszy z klasy Bj można jednym ruchem przejść do każdej z klas B^0,B^1,ldots,B^j-1.

Wiemy też, że nie zachodzi B_jsucc B_j, czyli z pewnej planszy z klasy Bj nie da się wykonać ruchu tak, by pozostać w klasie Bj. Prawdą jest jednak mocniejsze stwierdzenie: nigdy nie da się wykonać ruchu tak, by pozostać w tej samej klasie. Dowód jest bardzo prosty: gdyby tak było dla pewnej planszy xin B, to na planszy xcup x gracz pierwszy wykonałby to posunięcie na jednej z połówek, doprowadzając do sytuacji x'cup x, gdzie x,x'in B, czyli [x]=[x']=B, skąd [x'cup x]=0. Z sytuacji dla siebie przegrywającej xcup x przeszedłby zatem do sytuacji, w której przegrać musi jego oponent, co oczywiście jest sprzeczne z naszymi definicjami i ze zdrowym rozsądkiem.

Widzimy zatem co następuje: numer planszy x to jedyna taka liczba j, że z planszy x da się jednym posunięciem przejść do każdej z klas B^0,B^1,ldots,B^j-1, i nie da się żadnym posunięciem przejść do żadnej spośród plansz, należących do klasy Bj.

Ta obserwacja poprowadzi nas już prosto do algorytmu, który indukcyjnie wyznacza numery klas plansz. Dla porządku przytoczę jeszcze tylko jedną definicję:

Definicja. Jeśli Y z działaniem + jest grupą, a Y'subseteq Y takim podzbiorem, który również jest grupą ze względu na to samo działanie, to mówimy, że Y' jest podgrupą Y.

Przykładowo, liczby całkowite podzielne przez 3 stanowią podgrupę grupy liczb całkowitych z dodawaniem.

Oznaczmy przez X_msubseteq X zbiór wszystkich plansz, zbudowanych z obszarów, z których żaden nie jest dłuższy niż m. Oczywiście X=X_p.

Niech cal X_m oznacza zbiór tych wszystkich klas plansz (elementów grupy ^X/_equiv), które mają reprezentanta z Xm. Jest on zamknięty ze względu na działanie cup i oczywiście jest podgrupą grupy ^X/_equiv. Mamy zatem 0=cal X_0subseteqcal X_1su.... Zauważmy też, że każdy ze zbiorów cal X_m składa się z klas o kolejnych numerach, od B0 do pewnego BN. Jest tak, gdyż jeśli N jest największą liczbą taką, że B^Nin cal X_m, to pewna plansza xin B^N składa się z obszarów nie dłuższych niż m. Można z niej jednym ruchem dojść do każdej z klas B^0,B^1,ldots,B^N-1, a ruch w grze w paski nie może spowodować, by którykolwiek z obszarów wydłużył się. To dowodzi, że każda z tych klas ma reprezentanta w Xm, czyli należy do cal X_m.

Podam teraz algorytm, który po każdym kroku dla kolejnych liczb m potrafi

Pierwszy krok algorytmu jest trywialny: wiemy, że plansza pusta ma numer 0, a grupa cal X_0=0 jest grupą trywialną.

Załóżmy więc, że potrafimy wyznaczać klasy dla plansz z X_m-1 oraz że dla takich klas potrafimy wykonywać działanie cup. Weźmy planszę xm zbudowaną z jednego obszaru długości m. Przejrzyjmy wszystkie możliwe ruchy, jakie możemy wykonać na tej planszy. Każdy z tych ruchów prowadzi do planszy zbudowanej z 1 lub 2 obszarów, z których każdy ma długość leq m-1. Zatem zgodnie z założeniem potrafimy wyznaczyć numery klas wszystkich tych plansz (jeśli jakiś ruch rozspaja naszą planszę, to numer klasy wyznaczymy, obliczając cup klas obu obszarów, na które rozpadła się nasza plansza). Mamy wówczas pewność, że klasa, do której należy xm, jest najmniejszą liczbą naturalną, jaka nie pojawiła się wśród otrzymanych numerów klas plansz. Jeśli np. możliwe ruchy prowadzą z xm do plansz z klas o numerach 0,1,2,3,6,9,13, to znaczy, że [x_m]=B^4.

Są tu dwie możliwości. Albo [x_m]in cal X_m-1, skąd wynika, że cal X_m=cal X_m-1 i nic więcej w tym kroku algorytmu nie musimy robić, albo z planszy xm można dojść do każdej z klas, należących do cal X_m-1, czyli klasa [x_m] nie jest nam jeszcze znana. Ten drugi przypadek musimy rozważyć dokładniej.

Wiemy, że cal X_m-1=B^0,ldots,B^M-... dla pewnego M. Stąd natychmiastowy wniosek, że [x_m]=B^M in cal X_msetmin....

Rozważmy teraz klasy postaci [x_m]cup B^j, gdzie 0leq jleq M-1.

W takim razie mamy

cal X_m= B^0,B^1,ldots,B^M...

Co więcej, skoro umieliśmy wykonywać działanie cup w grupie cal X_m-1, to pamiętając, że [x_m]cup [x_m]=0, umiemy je wykonać także w cal X_m!

Teraz już nietrudno zgadnąć, że numerem klasy [x_m]cup B^j będzie M+j. Aby się o tym przekonać, wybierzmy dowolnego reprezentanta xin B^j i rozważmy planszę x_mcup x. Na tej planszy możemy wykonać ruch albo w obrębie części xm, albo x.

Wykonując ruch w części x możemy przejść do dowolnie wybranej spośród klas [x_m]cup B^i, gdzie 0leq i<j. Być może uda nam się również przejść do którejś z klas [x_m]cup B^k dla k>j, ale dla każdego takiego k znajdziemy reprezentanta xin B^j, dla którego nie będzie to możliwe. Wszystko odbywa się analogicznie jak na samej planszy xin B^j, bez dołączonej części xm.

Natomiast kładąc pasek w części xm, możemy przejść do dowolnej klasy B'in cal X_m-1. Wystarczy wziąć B. Wiemy, że B, więc istnieje taki ruch na planszy xm, który prowadzi do klasy B". Wykonując ten ruch na planszy x_mcup x, istotnie otrzymamy w wyniku planszę klasy B. Widzimy też, że ruch w obrębie xm nie doprowadzi nas do żadnej klasy spoza cal X_m-1.

Podsumowując, widzimy wyraźnie, że:

B^M-1prec [x_m]=[x_m]cup B^0....

Ponieważ wiemy skądinąd, że cal X_m=B^0,ldots,B^2M-1, to musi rzeczywiście zachodzić [x_m]cup B^j=B^M+j, dla każdego 0leq jleq M-1.

W ten sposób z nawiązką wypełniamy wszystkie warunki indukcyjne, dotyczące naszego algorytmu.

Pozostaje jeszcze jeden drobiazg: widzimy, że po pierwszym kroku znamy tylko jedną planszę (pustą), a po każdym następnym liczba znanych nam plansz (tzn. liczba elementów grupy cal X_m) albo nie zmienia się, albo się podwaja. Będzie zatem zawsze potęgą dwójki. W szczególności, w całym powyższym rozumowaniu M było potęgą dwójki. Po tej uwadze nie powinno być dla Czytelnika najmniejszym problemem udowodnienie przez indukcję, że działaniu cup w grupie klas plansz odpowiada dokładnie operacja XOR na numerach tych klas.

W ten sposób wszystkie tajemnice gry w paski zostały ujawnione.

Testy

Na potrzeby testowania rozwiązań przygotowano 15 testów. Każdy z nich zawierał p przypadków plansz do rozpatrzenia - było to zawsze kolejno p plansz o długościach od 1 do p.

W poniższej tabeli zestawiono wartości c, z, n oraz p dla poszczególnych testów. Ponadto, k oznacza największą liczbę taką, że co najmniej jedna z plansz xm przy mleq p należy do klasy Bk. Dalej, W1 oznacza liczbę tych plansz spośród x_1,...,x_p, które są wygrywające dla gracza rozpoczynającego (czyli należą do klasy Bj dla j>0), zaś W2 - liczbę plansz przegrywających dla rozpoczynającego.

 vtophalign&hfil#quadcr quad...

Testy 4 i 5 oraz 6, 7, 8 i 9 zostały zgrupowane.

Podsumowanie

Zadanie "Paski" było prawdopodobnie jednym z najtrudniejszych zadań w historii Olimpiady. Mimo że było zadaniem z pierwszego etapu, a więc można było poświęcić na nie wiele czasu i posiłkować się przy pracy literaturą, to jednak poprawnie rozwiązał je tylko jeden zawodnik.

Przedstawione w niniejszym artykule rozumowanie jest oparte na dowodzie poprawności programu wzorcowego. Autorem tego programu i dowodu jest Tomasz Waleń.

Podstawowe pojęcia teorii gier są przystępnie objaśnione w pierwszym rozdziale znakomitej książki [HS]. Serdecznie zachęcam do lektury!

Czytelnikom zainteresowanym tematem polecam również pozycję [JC], a w szczególności zawarte tam informacje o grze Nim. Gra ta okazuje się mieć wiele wspólnego z grą w paski. W niej także do znalezienia strategii wygrywającej przydaje się operacja XOR.

Bibliografia


  [HS] Hugo Steinhaus "Kalejdoskop matematyczny", WSiP Warszawa 1989


  [JC] John Conway "On Numbers and Games", Academic Press, Inc. New York 1976