Przeskocz do treści

Delta mi!

Informatyczny kącik olimpijski

Palindromy

Filip Wolski

o artykule ...

  • Publikacja w Delcie: czerwiec 2009
  • Publikacja elektroniczna: 02-06-2014

W tym kąciku informatycznym – zadanie Palindromy z finału XIII Olimpiady Informatycznej.

obrazek

Zadanie. Mamy danych math różnych palindromów (czyli słów, które są takie same czytane od początku, jak i od końca) złożonych z małych liter alfabetu angielskiego (a więc mamy co najwyżej math różnych liter). Wiemy, że sumaryczna długość wszystkich palindromów jest nie większa niż math  Pytanie jest następujące: ile jest różnych par (uporządkowanych) podanych palindromów, które sklejone dają także palindrom?

Na początku wprowadźmy kilka oznaczeń. Jeśli math  jest słowem, to przez math oznaczymy math  czytane od tyłu. Zatem math  jest palindromem, jeśli math  Dalej, przez math  oznaczymy prefiks math  o długości math (a więc pierwsze math liter słowa math ), za to przez math – sufiks math  o długości math (tj. math ostatnich liter math ). I jeszcze, niech math będzie długością słowa math

Zacznijmy od kilku spostrzeżeń, które narzucają się po przeanalizowaniu choćby przykładu do tego zadania – Czytelnikowi proponuję rozpisanie własnego i przyjrzenie mu się. Po pierwsze, na pewno każdy palindrom math  z wejścia zwiększa wynik co najmniej o  math Jest tak dlatego, że skoro math  to math  Po drugie, niech math  i  math będą takimi palindromami, że math  też jest palindromem, oraz niech math (zachodzi albo to, albo nierówność w drugą stronę – długości nie mogą być sobie równe, bo wtedy mielibyśmy math ). Wtedy math  również jest palindromem. Faktycznie, zachodzi math  a ponadto math jest palindromem, więc math również. Łatwo zauważyć, że występuje tutaj równoważność, czyli jeśli math  jest palindromem, to math  również.

Sumarycznym wynikiem jest więc math gdzie math to liczba takich par różnych palindromów math  że math

No to teraz możemy zastanowić się nad tym, kiedy dwa palindromy math  i  math math tworzą palindrom math  Na pewno trzeba, żeby math  czyli żeby math  było prefiksem math Poza tym jeszcze math musi być palindromem (jest to środek math  po ucięciu z początku i z końca math liter). Na bazie tych dwóch warunków zbudujemy już rozwiązanie zadania.

Zacznijmy od tego, jak znaleźć wszystkie palindromy math  z wejścia, będące prefiksami palindromu math Załóżmy, że wejście jest posortowane leksykograficznie. Zauważmy, że jeśli math  jest prefiksem math to w kolejności leksykograficznej między nimi mogą znaleźć się tylko takie słowa math że math  jest prefiksem math Załóżmy, że mamy policzoną listę math wszystkich spośród naszych palindromów, które są prefiksami math  występuje bezpośrednio przed math w kolejności leksykograficznej oraz znamy maksymalne możliwe math spełniające math (obliczenie takiego math to koszt math ). Wtedy lista wszystkich spośród naszych słów, które są prefiksami math to lista math uzupełniona o  math z której zostały usunięte wszystkie słowa dłuższe niż math Długość tej listy dla math jest ograniczona przez długość math (na wejściu mamy parami różne palindromy), a więc cała operacja otrzymania listy dla math z listy dla math ma koszt math

W drugim kroku chcielibyśmy sprawdzić, dla danej pary palindromów math  i  math gdzie math  występuje na liście odpowiadającej math czy rzeczywiście math  jest palindromem, czyli czy math też nim jest. math jest palindromem wtedy i tylko wtedy, gdy math

A w takim razie math musi być jednocześnie i prefiksem, i sufiksem słowa math A to już brzmi znajomo – w tym momencie warto skorzystać z algorytmu Knutha–Morrisa–Pratta (Czytelnikowi nieobeznanemu z tym algorytmem polecam skorzystanie z mnóstwa materiałów dostępnych w Internecie). W tym algorytmie wyznaczana jest tablica prefiksowa math w której math jest długością najdłuższego prefiksu, będącego jednocześnie sufiksem słowa math Zauważmy, że długością najdłuższego prefiksu, będącego jednocześnie sufiksem math jest math następnego najdłuższego – math itd., aż w końcu math Algorytm KMP oblicza tablicę math w czasie math  a my w takim samym czasie możemy odczytać z niej długości wszystkich prefiksów math będących sufiksami math czyli palindromami. Po tych wstępnych obliczeniach można już natychmiastowo sprawdzić, dla każdego palindromu math  z listy odpowiadającej math czy math jest palindromem.

W takim razie sumaryczny czas, jaki musimy poświęcić math jest rzędu math  gdzie math jest poprzednim leksykograficznie palindromem, a więc sumaryczny czas całego algorytmu, nie licząc sortowania, to math  Czytelnikowi pozostawiam sprytną implementację algorytmu sortowania pozycyjnego tak, żeby złożoność całego algorytmu pozostała math  Liczba „obrotów” sortowania może być bliska math  ze względu na rozmiar alfabetu – chociaż tę stałą da się znacząco zmniejszyć, co również polecam jako ćwiczenie.