Marcin Jurdziński | Tomasz Waleń |
Treść zadania, Opracowanie | Program wzorcowy |
Gra w zielone jest grą dla dwóch graczy - nazwijmy ich Ania i Bolek - polegającą na przesuwania pionka po planszy.
Część pól planszy jest pokolorowana na zielono, a pozostałe są białe. Wszystkie pola są ponumerowane liczbami naturalnymi z zakresu 1... (a+b), pola o numerach z zakresu 1... a należą do Ani, natomiast pola o numerach (a+1)... (a+b) należą do Bolka.
Dla każdego pola dany jest zbiór następników, zawierający te pola planszy, do których można z niego przejść w jednym ruchu. Zbiory te zostały tak dobrane, że z pola należącego do Ani można przejść w jednym ruchu tylko na pole należące do Bolka i odwrotnie.
Na początku gry ustawiamy pionek na dowolnym polu, a następnie gracze na przemian przestawiają pionek ze swojego pola na dowolny następnik tego pola - należący do przeciwnika. Grę rozpoczyna właściciel pola, z którego zaczynamy rozgrywkę. Zakładamy, że wszystkie pola mają niepuste zbiory następników, a więc zawsze można wykonać ruch. Gra kończy się w momencie, gdy pionek stanie po raz drugi na tym samym polu. Jeśli w sekwencji ruchów, od pierwszego do powtórnego zajęcia tego pola, pionek stanął przynajmniej raz na polu zielonym, to wygrywa Ania, w przeciwnym przypadku wygrywa Bolek.
Powiemy, że Ania ma strategię wygrywającą dla danego pola początkowego, jeśli istnieje metoda gwarantująca jej wygraną w rozgrywce zaczynającej się od tego pola, niezależnie od tego, jakie ruchy będzie wykonywał Bolek.
Napisz program, który:
W pierwszym wierszu pliku tekstowego gra.in zapisane są dwie nieujemne liczby całkowite a, b oddzielone pojedynczym odstępem, oznaczające odpowiednio: liczbę pól należących do Ani i liczbę pól należących do Bolka. Liczby a, b spełniają warunek: . W kolejnych a+b wierszach opisano pola planszy - najpierw pola należące do Ani, a następnie pola należące do Bolka. Wiersz o numerze i+1, dla , zawiera na początku liczby całkowite z, k oddzielone pojedynczym odstępem, oznaczające odpowiednio kolor pola o numerze i (0 oznacza kolor biały, 1 - kolor zielony), oraz liczbę następników tego pola. Następnie w tym wierszu zapisane jest k liczb całkowitych (), pooddzielanych pojedynczymi odstępami, będącymi numerami następników danego pola. Liczba pól zielonych na planszy nie przekracza 100. Suma liczb następników wszystkich pól na planszy nie przekracza 30 000.
Pierwszy wiersz pliku tekstowego gra.out powinien zawierać dokładnie jedną liczbę całkowitą p, oznaczającą liczbę pól, dla których Ania ma strategię wygrywającą. Następne p wierszy powinno zawierać numery tych pól zapisane w kolejności rosnącej - każda liczba powinna zostać zapisana w osobnym wierszu.
5 3 0 2 6 7 0 3 6 7 8 0 1 8 1 1 7 1 1 8 1 2 1 2 0 2 1 2 0 2 3 4poprawną odpowiedzią jest plik wyjściowy gra.out
5 1 2 4 6 7
Ścisłe sformułowanie faktu, że w grze w zielone Ania ma strategię wygrywającą z danego pola początkowego nie jest banalne i jest zaledwie naszkicowane w treści zadania. Jego sprecyzowanie oraz algorytmiczną charakteryzację należy zatem do pewnego stopnia traktować jako część zadania postawionego przed uczestnikami olimpiady.
Przez P będziemy oznaczać zbiór wszystkich pól na planszy, a przez Z zbiór wszystkich pól zielonych.
Aby ułatwić opis strategii wygrywających w grze w zielone oraz ich poszukiwanie, wygodnie jest rozważyć następującą uproszczoną wersję gry. Niech będzie pewnym zbiorem zielonych pól na planszy. Uproszczona gra w zielone toczy się w sposób podobny do zwyczajnej gry w zielone. Różnica polega na tym, że w uproszczonej grze w zielone rozgrywka może się zakończyć wcześniej: gdy pionek odwiedzi zielone pole ze zbioru X po raz pierwszy, rozgrywka zostaje przerwana i Ania zwycięża.
Przez Wymuś(X) oznaczamy zbiór pól, z których Ania ma strategię wygrywającą w uproszczonej grze w zielone. Zauważ, że Wymuś(X) jest zbiorem pól z których Ania może wymusić przesunięcie pionka na pewne zielone pole ze zbioru X w taki sposób, że pionek nie staje na żadnym polu dwa razy.
W poniższym fakcie wykazujemy, że rozwiązanie uproszczonej gry w zielone dla X = Z, tj. obliczenie zbioru Wymuś(Z), jest pomocne w ustaleniu pewnego zbioru pól, z których Bolek ma strategię wygrywającą w normalnej grze w zielone.
Fakt: Strategia wygrywająca dla Bolka Dowód.
Fakt, że pole p nie należy do zbioru Wymuś(Z) oznacza,
że w uproszczonej grze w zielone rozpoczynającej się w polu p,
Bolek potrafi zapobiec dojściu do jakiegokolwiek zielonego pola.
Cała rozgrywka toczy się więc i kończy w białej części planszy -
to gwarantuje zwycięstwo Bolka w zwyczajnej grze w zielone z
pola p.
Przykład: Zauważ, że oraz
Wymuś.
W polach spoza zbioru Wymuś(Z), tj. w polach ze zbioru
, Bolek ma strategię wygrywającą polegającą na
wybraniu pola 3 jako następnika w polu 8.
Następnie spróbujemy ustalić jakie warunki gwarantują, że
strategia wygrywająca dla Ani w uproszczonej grze w zielone daje
Ani zwycięstwo także w normalnej grze w zielone.
W tym celu przydatne okazuje się pojęcie pułapki dla Bolka.
Definicja: Pułapka dla Bolka Przykład: Fakt: Strategia wygrywająca dla Ani Dowód.
Rozważmy następującą strategię dla Ani:
Pozostaje nam do rozwiązania sytuacja, w której zbiór
Wymuś(Z) nie jest pułapką dla Bolka.
Niech będzie zbiorem zielonych pól, które
spełniają warunki [5]lub [6] definicji pułapki dla Bolka, dla
X = Z.
Zauważ, że w zielonych polach nie należących do zbioru Z1, Bolek
ma następującą strategię wygrywającą:
najpierw przesuń pionek w jednym kroku do pola nie należącego do
zbioru Wymuś(Z), a następnie użyj strategii wygrywającej
zagwarantowanej przez
Fakt [2].
Możemy zatem odrzucić zielone pola spoza zbioru Z1, jako
``bezużyteczne'' dla Ani.
Aby ponowić próbę użycia
Faktu [8] do wyznaczenia
strategii wygrywającej dla Ani, rozważmy zbiór
Wymuś(Z1).
Jeśli ten zbiór jest pułapką dla Bolka, to rozwiązanie gry w
zielone jest gotowe
(można wykazać - patrz dowód ogólniejszego
Faktu []
poniżej - że także we wszystkich białych polach spoza zbioru
Wymuś(Z1) Bolek ma strategię wygrywającą.)
W przeciwnym wypadku należy ponownie odrzucić zielone pola, które
okazały się bezużyteczne dla Ani, itd.
Powyższe rozumowanie motywuje następującą metodę obliczania
kolejnych, coraz mniejszych zbiorów zielonych pól, które kandydują
do roli pól dających Ani strategię wygrywającą (poprzez
Fakt [8]).
Bolek ma strategię wygrywającą z każdego pola, które nie jest w
zbiorze Wymuś(Z).
W tym i w poniższych przykładach ilustrujemy pojęcia i fakty
opisane w tym opracowaniu na przykładzie gry w zielone z
przykładu z treści zadania.
Powiemy, że zbiór pól Wymuś(X) jest pułapką
dla Bolka, jeśli dla każdego pola p ze zbioru X mamy:
Niech .
Zbiór Wymuś jest pułapką dla Bolka,
ponieważ:
Jeśli zbiór Wymuś(X) jest pułapką dla Bolka, to Ania ma
strategię wygrywającą z każdego pola w zbiorze Wymuś(X).
Zauważ, że w każdej rozgrywce zgodnej z tą strategią, pionek nigdy
nie opuszcza zbioru Wymuś(X).
Co więcej, żaden cykl
(tj. fragment rozgrywki rozpoczynający się i kończący w tym samym
polu)
w takiej rozgrywce nie składa się tylko z
białych pól, ponieważ strategia Ani na białych polach jest
wygrywająca w uproszczonej grze w zielone.
Dlatego każda rozgrywka zgodna z powyższą strategią jest
wygrywająca dla Ani w zwyczajnej grze w zielone.
1 | procedure NajwiększaPułapkaDlaBolka |
2 | begin |
3 | Z0 := Z |
4 | i := 0 |
5 | while Wymuś(Zi) nie jest pułapką dla Bolka do |
6 | begin |
7 | zbiór pól z Zi spełniających warunki~\ref{definicja:pulapka-1}\ lub~\ref{definicja:pulapka-2}\ definicji~\ref{definicja:pulapka-dla-bolka} |
8 | i := i + 1 |
9 | end |
10 | end |
Przykład:
Zauważ, że jeśli warunek kontynuacji wykonywania pętli 5:-9: jest spełniony, to istnieje przynajmniej jedno zielone pole w zbiorze Zi nie spełniające warunków 1 lub 2definicji [4]. Dlatego ciąg zbiorów Zi jest malejący, a stąd wynika, że liczba iteracji pętli 5:-9: wynosi O(k).
Niech będzie najmniejszą liczbą dla której zbiór Wymuś jest pułapką dla Bolka. Oczywiście Ania ma strategię wygrywającą ze zbioru Wymuś - wynika to z Faktu [8]. Aby wykazać, że Wymuś to zbiór wszystkich pól z których Ania ma strategię wygrywającą, wystarczy udowodnić, że z każdego pola spoza zbioru Wymuś, strategię wygrywającą ma Bolek.
Fakt: Strategia wygrywająca dla Bolka: ogólny przypadek
Dowód. Dowód przebiega przez indukcję ze względu na i. Zauważ, że dla i = 0 teza wynika wprost z Faktu [2].
Załóżmy, że dla pewnego , Bolek ma strategię wygrywającą z każdego pola spoza zbioru Wymuś(Zi). Wykażemy, że wtedy Bolek ma także strategię wygrywającą z każdego pola spoza zbioru Wymuś.
Wystarczy udowodnić, że Bolek ma strategię wygrywającą z każdego pola ze zbioru WymuśWymuś - dla pól nie należących do zbioru Wymuś(Zi) teza wynika z hipotezy indukcyjnej.
Rozważmy dwa rodzaje pól ze zbioru WymuśWymuś:
Aby precyzyjnie oszacować koszt czasowy działania algorytmu NajwiększaPułapkaDlaBolka musimy ustalić, jaki jest koszt rozwiązywania uproszczonej gry w zielone, tj. obliczania zbioru Wymuś(X). Powiemy, że warunek AniaWymusza(T, p) zachodzi dla pewnego zbioru pól T, oraz pola p, jeśli mamy:
Ćwiczenie: Poprawność algorytmu ObliczZbiórWymuś
1 | procedure ObliczWymuś(X) |
2 | begin |
3 | |
4 | while istnieje pole takie, że \emph{AniaWymusza}(W, p) do |
5 | dodaj pole p do zbioru W |
6 | {\bf return}(W) |
7 | end |
Procedurę ObliczWymuś można zaimplementować tak, aby działała w czasie O(m), gdzie m jest sumą liczb następników dla wszystkich pól. Przykładowa implementacja znajduje się na załączonej dyskietce.
Powyższą algorytmiczną analizę struktury strategii wygrywających dla Ani i Bolka w grze w zielone można podsumować w następujący sposób.
Twierdzenie: Poprawność algorytmu
NajwiększaPułapkaDlaBolka
W tym podrozdziale omówimy alternatywny warunek wystarczający i konieczny dla istnienia strategii wygrywających dla Bolka lub Ani w Grze w Zielone. Interesującą cechą tego warunku jest jego lokalność: jeśli każde pole jest w odpowiedniej, dość łatwej do sprawdzenia relacji ze zbiorem jego następników, to mamy gwarancję, że istnieje ``globalna'' strategia wygrywająca dla odpowiedniego gracza.
Definicja: Dobre etykietowanie dla Bolka
Dowód: Wykażemy, że następująca strategia jest wygrywająca dla Bolka: w każdym polu p należącym dla Bolka, Bolek wybiera następnika r pola p, o jak najmniejszej etykiecie . Zauważmy, że z definicji dobrego etykietowania dla Bolka wynika, że wtedy dla każdej rozgrywki p1, p2, p3, ..., pi mamy
1 | procedure PodnośEtykietowanie |
2 | begin |
3 | dla każdego pola p do |
4 | while nie jest dobre dla Bolka do |
5 | begin |
6 | wybierz pole p w którym nie jest dobre dla Bolka |
7 | |
8 | end |
9 | end |
Powyższy fakt oznacza, że istnienie dobrego etykietowania dla Bolka, dla którego zachodzi , jest warunkiem wystarczającym dla istnienia strategii wygrywającej dla Bolka z pola p. Poniżej naszkicujemy dowód faktu, że jest to również warunek konieczny, oraz przedstawimy wydajny sposób znajdowania dobrych etykietowań. Rozważmy następującą procedurę poszukiwania dobrego etykietowania dla Bolka:
gdzie Popraw to najmniejsza etykieta nie mniejsza od , która przypisana polu p gwarantuje, że etykietowanie staje się dobre w polu p. Wartość Popraw można obliczyć na przykład tak:
Przykład:
Dla skrócenia i uproszczenia ilustracji działania algorytmu
PodnośEtykietowanie |
Można myśleć o procedurze PodnośEtykietowanie jako o metodzie przybliżania etykietowania ,,z dołu'', do ,,najmniejszego'' dobrego etykietowania. Istotnie, początkowe etykietowanie , gdzie , dla każdego pola p, jest ,,mniejsze'' niż jakiekolwiek inne etykietowanie. (Dla ścisłości, mówimy, że etykietowanie jest ,,mniejsze'' lub równe niż etykietowanie , jeśli , dla każdego pola p.) Kolejne ,,poprawki'' polegające na podnoszeniu wartości etykietowania w polu, w którym nie jest dobre dla Bolka, zachowują własność, że etykietowanie jest mniejsze lub równe niż każde dobre etykietowanie. Jest tak dlatego, ponieważ w procedurze PodnośEtykietowanie wartość etykiety w pewnym polu jest zawsze podnoszona tylko o tyle, o ile to jest konieczne, aby etykietowanie stało się dobre dla Bolka w tym polu.
Przykład:
Etykietowanie :
Zauważ, że każde pole może być poprawione przez procedurę PodnośEtykietowanie co najwyżej k+1 razy, zatem liczba powtórzeń pętli 4:-8: wynosi .
Co więcej, etykietowanie po zakończeniu procedury PodnośEtykietowanie jest dobrym etykietowaniem dla Bolka; w ,,najgorszym'' przypadku mamy , dla każdego pola p - ,,największe'' dobre etykietowanie. Z faktu [13] wynika, że Bolek ma strategię wygrywającą z każdego pola p takiego, że . Najmniejsze dobre etykietowanie dla Bolka, tj. etykietowanie obliczane przez procedurę PodnośEtykietowanie, jest szczególnie interesujące ponieważ można z niego łatwo odczytać rozwiązanie gry w zielone, tj. zbiór pól z których istnieje strategia wygrywająca dla Ani.
Twierdzenie: Strategia wygrywająca dla Ani
Dowód tego twierdzenia nie jest natychmiastowy i wymaga dość subtelnej argumentacji. Poniżej szkicujemy przydatne w tym celu pojęcia oraz ogólny tok rozumowania. Wypełnienie szczegółów dowodu pozostawiamy jako ćwiczenie dla dociekliwego czytelnika.
Definicja: Dobre etykietowanie dla Ani
Przykład:
Podobnie jak w przypadku dobrych etykietowań dla Bolka, można
skonstruować strategię wygrywającą dla Ani, jeśli dane jest
dobre etykietowanie dla Ani.
Dowód następującego łatwego faktu pozostawiamy czytelnikowi.
Ćwiczenie: Strategia wygrywająca dla Ani W celu wykazania
Twierdzenia [15]
do procedury PodnośEtykietowanie dodamy instrukcje
obliczające etykietowanie
.
Zauważ, że te dodatkowe instrukcje nie mają wpływu na obliczenie
etykietowania i służą nam tylko jako pomoc w dowodzie
Twierdzenia [15].
Rozważmy następującą modyfikację procedury
PodnośEtykietowanie:
Etykietowanie
zdefiniowane przez następującą tabelę jest dobre dla Ani.
Wykaż, że jeśli etykietowanie
jest dobre dla Ani, to Ania ma strategię wygrywającą z każdego
pola p takiego, że .
1 | procedure PodnośEtykietowanie' |
2 | begin |
3 | dla każdego pola p do begin ; end |
4 | while nie jest dobre dla Bolka do |
5 | begin |
6 | wybierz pole p w którym nie jest dobre dla Bolka; |
7 | ; |
8 | if then |
9 | end |
10 | end |
gdzie
Przykład:
PodnośEtykietowanie' |
Ćwiczenie: Dobre etykietowanie dla Ani
Powyższą analizę dobrych etykietowań dla Ani i Bolka można podsumować w następujący sposób.
Twierdzenie: Poprawność algorytmu
PodnośEtykietowanie
Ćwiczenie: Wydajna implementacja algorytmu
Ciekawy problem:
Przyjmijmy, że liczba zielonych pól wynosi
.
Czy istnieje algorytm rozwiązujący gry w zielone działający w
czasie ?
W szczególności, czy istnieje algorytm rozwiązujący gry w
zielone działający w czasie O(m)?
Ocena rozwiązań zadania ``Gra w zielone'', przedstawionych przez uczestników olimpiady, została oparta na zachowaniu się programów na kolekcji jedenastu testów, tj. jedenastu plików wejściowych zawierających opisy plansz różnych gier w zielone: