Középiskolai Matematikai és Fizikai Lapok
Informatika rovattal
Kiadja a MATFUND Alapítvány
Már regisztráltál?
Új vendég vagy?

Az S. 58. feladat (2010. december)

S. 58. A Bergengóc Királyságban évezredes hagyományokkal rendelkező esemény a Nemzetközi Máguskonferencia, melynek minden évben az egyik legkedveltebb és leglátványosabb műsorszáma a Nagyotmondók Viadala. Ennek keretében az ország legkiválóbb mágusai mérik össze tudásukat: a nyertes az, aki a rendelkezésre álló időkeret alatt a leghosszabb varázsszót mondja ki -- a legkülönfélébb csodás mellékhatásokkal.

Sajnos az előző évben a rendezvény túlontúl látványosra sikeredett, s a konferencia után a főváros helyreállítása hónapokig tartott. Ennek megelőzése érdekében a király idén elrendelte, hogy a versenyen kizárólag olyan varázsszavakkal lehet indulni, melyek előállnak páros hosszú tükörszavak egymás után írásával, ezekről ugyanis köztudott, hogy veszélytelenek.

Készítsünk programot, mely a versenyzők által előadni kívánt, előzetesen leadott varázsszavakról eldönti, hogy a fenti módon felbonthatók, azaz a versenyen biztonsággal előadhatóak-e, és ha igen, akkor meg is ad egy-egy ilyen felbontást.

A standard bemenet első sorában egyetlen egész szám: a vizsgálandó varázsszavak N száma szerepel (1\leN\le100), azt ezt követő N darab sor pedig egy-egy varázsszót tartalmaz. Feltehetjük, hogy minden varázsszó kizárólag az angol ábécé kisbetűiből áll, legfeljebb 1 000 000 karakter hosszú, illetve -- amennyiben biztonságos -- legfeljebb 5000 karakter hosszú tükörszavakból épül fel.

A standard kimenetre pontosan N darab sor kerüljön, az i-edik sor a bemenet i-edik varázsszavának értékelését tartalmazza. Amennyiben a varázsszó biztonságos, akkor a sor elején a felbontásban szereplő részszavak K száma szerepeljen (K\ge1), majd ezt kövessék a felbontás elemei, szóközzel elválasztva. Ellenkező esetben a sorba mindössze egy ,,0'' számjegyet írjunk. Több megoldás esetén bármelyik megadható.

Beküldendő a feladat megoldását tartalmazó forrás és projektállományok (az .exe és más a fordító által generált kiegészítő állományok nélkül), valamint a megoldás menetét röviden bemutató dokumentáció (s58.txt, s58.pdf, ...) egy tömörített mappában (s58.zip).

(10 pont)

A beküldési határidő 2011. január 10-én LEJÁRT.


Megoldás

Még ha egy részszóról gyorsan el is tudnánk dönteni, hogy tükörszó-e, akkor is felmerül a kérdés: hogyan tudunk hatékonyan meghatározni egy olyan felbontást, amelynek minden eleme tükörtulajdonságú?

Szerencsére a mohó módszer itt működik: megtehetjük, hogy a varázsszó egyre növekvő hosszúságú kezdőszeleteiről megvizsgáljuk, hogy tükör-e, és ha igen, levágjuk, majd a maradékra újból ugyanezt végezzük. Ha sikerül elfogyasztani a varázsszót, pontosan akkor biztonságos.

Ez helyes. Az egyedüli nehéz irány annak megmutatása, hogy ha van felbontás, akkor azt meg is találjuk. Ez pedig igaz, hiszen ha az algoritmusunk nem a felbontás első darabját, w-t találja meg, akkor annak egy v kezdőszeletét találhatta csak meg (hiszen növekvő hossz irányában dolgozik). Ha |v|\leq|w|/2, akkor w tükörtulajdonsága miatt w=vxx'v' alakú, ahol x w első felének azt a részét jelöli, melyet v nem fed le, az aposztróf pedig a tükrözés. Ekkor viszont a felbontásban w-t lecserélhetjük v, xx' és v'-re, hiszen egy tükörszó tükrözöttje is tükörszó, tehát van olyan felbontás is, melynek v az első eleme.

Hasonlóan, megmutatható hogy |v|>|w|/2 nem lehetséges, mert akkor már korábban kellett volna egy tükörszó kezdőszeletet találnunk.

Ezek után az egyetlen kérdés, hogy miként döntsük el egy kezdőszeletről, hogy tükörszó-e. Ezt Manacher jól ismert algoritmusával a varázsszó hosszában összesen lineáris időben meghatározhatjuk.

C++ mintamegoldás


Statisztika:

10 dolgozat érkezett.
10 pontot kapott:Barta 111 János, Borsos 607 Zalán, Szabó 928 Attila.
8 pontot kapott:4 versenyző.
7 pontot kapott:1 versenyző.
6 pontot kapott:2 versenyző.

A KöMaL 2010. decemberi informatika feladatai