Nemzetközi Informatikai Olimpia 2001

Tampere, Finnország



Mobil telefonok - 1. Nap, 1. feladat (100 pont, időlimit: 1 mp tesztesetenként) /tesztadatok/
A tamperei negyedik generációs mobiltelefon-körzet SxS db cellára van osztva. Az egyes cellákban változhat az aktív mobiltelefonok száma (a telefonokat bekapcsolják, kikapcsolják, illetve más cellába viszik át). A változásokról a központ értesítést kap. Írj olyan programot, amely fogadja a változásokról szóló értesítéseket, és válaszol azokra a kérdésekre, amelyek tetszőleges téglalap-alakú területen az aktív mobil-telefonok számát tudakolja.

Bemenet és kimenet:

A program egész számokat olvas be a standard inputról és egész számokat ír ki a standard outputra. Az input sorokból áll, minden sor egy utasításkóddal kezdődik, amelyet paraméterek követhetnek (lásd az alábbi táblázatot).
 
Utasításkód Paraméterek Jelentés
0 S Az SxS méretű mátrix celláit feltölti nullákkal.
1 X Y A Adj A-t az (X, Y) cellában levő aktív mobiltelefonok számához. A lehet pozitív és negatív is.
2 L B R T Add meg az összes (X,Y) cellában levő aktív mobiltelefonok számát, ahol L <= X <= R, B <= Y <= T
3   Fejezd be a futást.

A 0 kódú utasítást, amelyből csak egy van, elsőként kapja meg a program, a 3 kódú utasítást pedig, amelyből ugyancsak egy van, utolsóként. A paraméterek értéke biztosan helyes, helyességüket nem kell ellenőrizni. Ha A negatív, a cellában levő érték a csökkentés után sem lesz negatív. A cellákat soronként és oszloponként 0-tól (S-1)-ig számozzuk. (Például S=4 esetén 0 <= X, Y <= 3.)

A programnak csak a 2 kódú utasításokra kell válaszolnia, mégpedig egy egész számot (az adott terület celláiban található aktív mobiltelefonok számát) tartalmazó sort kell kiírnia a standard outputra.

Programozási tanácsok:
Az alábbi példákban a last egész változó a sorból legutoljára beolvasott értéket tárolja, az answer egész változóban pedig a kiírandó eredménynek kell lennie.

Ha C++ nyelven az iostreams modult használod, a következőképpen olvass, illetve írj:

cin>>last;
cout<<answer<<endl<<flush;
Ha C vagy C++ nyelven a scanf és printf eljárásokat használod, a következőkép-pen olvass, illetve írj:
scanf ("%d", &last);
printf("%d\n",answer); fflush (stdout);
Pascal nyelven a következőképpen olvass, illetve írj:
Read(last); ... Readln;
Writeln(answer);
Példa:
 
Bemenet Kimenet Magyarázat
0 4   Létrehozza és nullázza a 4x4-es mátrixot.
1 1 2 3   Növeli az (1,2) cella értékét 3-mal.
2 0 0 2 2   Lekérdezi a 0 <= X <= 2,  0 <= Y <=  2 téglalap
ktív mobiltelefonjainak számát.
  3 Válaszol a kérdésre.
1 1 1 2   Növeli az (1, 1) cella értékét 2-vel.
1 1 2 -1   Csökkenti az (1, 2) cella értékét 1-gyel.
2 1 1 2 3   Lekérdezi az 1 <= X <= 2,  1 <= Y <= 3 téglalap
aktív mobiltelefonjainak számát.
  4 Válaszol a kérdésre.
3   Befejezi a programot.

Korlátok:

 
A mátrix mérete SxS 1x1 <= SxS <= 1024x1024
A cella V értéke bármely időpontban V 0 <= V <= 215 –1  (= 32767)
A csökkentés/növelés értéke -215 <= A <= 215–1  (= 32767)
Az utasítások száma 3 <= U <= 60002
A mobiltelefonok maximális száma az egész mátrixban  M M= 230

A 20 tesztesetből 16-ban a mátrix mérete legfeljebb 512 x 512 lesz.

Megjegyzés:
A web-es tesztelő az inputként megadott állományt a programod standard inputjára irányítja át.


IOIWari játék - 1. Nap, 2. feladat (100 pont, időlimit: 1 mp) /tesztadatok/
A Mancala családba tartozó játékok, amelyeket gyöngyökkel és üregekkel játszottak, a legősibbek közül valók. A wari játék IOI-s változatát két játékos játssza olyan kör alakú táblán, amelyben hét üreg van. A játék kezdetén az üregekbe véletlenszerűen beraknak húsz gyöngyöt úgy, hogy minden üregbe legalább két és legfeljebb négy gyöngy kerüljön. Mindkét játékosnak van egy-egy tálkája. A játékosok felváltva lépnek. A soron következő játékos kiválaszt egy nem üres üreget, a kezébe veszi belőle az összes gyöngyöt, és az óra járásával megegyező irányban haladva, a kiürített üreg szomszédjával kezdve, az alábbiakat teszi, amíg van gyöngy a kezében:
  A játék akkor ér véget, ha minden üreg kiürült, és az a játékos győz, akinek a tálká-jában több gyöngy van.

A kezdőjátékosnak mindig van nyerő stratégiája. Írj olyan programot, amely kezdőjátékosként Ioiwarit játszik, és győz. Az értékeléskor az ellenfelet megvalósító program optimálisan játszik, azaz biztosan győz, ha lehetőséget adsz rá.

Bemenet és kimenet:

Az adatokat a standard inputról kell beolvasni, és a standard outputra kell kiírni. A programod az 1-es, az ellenfél programja a 2-es játékos.

A játszma kezdetén a programodnak egy sort kell beolvasnia, amelyben hét egész szám, az 1-től 7-ig számozott üregekben lévő gyöngyök száma van (az üregeket az óramutató járása szerinti sorrendben számozzuk). A tálkák kezdetben üresek. A programodnak az alábbiak szerint kell működnie:

Segédeszközök:
Kapsz egy programot (Linux: ioiwari2, Windows: ioiwari2.exe), amely optimális ellenfélként játszik az alábbi kezdőállásból. Először ezt írja ki a standard outputra, amit a programodnak kezdéskor be kell olvasnia: 4 3 2 4 2 3 2.

A programodat és az ioiwari2-t külön ablakban futtasd, és az egyik program által kiírtakat másold át a másik programnak! Az ioiwari2 a párbeszédet az ioiwari.out állományba is beírja.

Programozási tanácsok:
Az alábbi példákban a last egész változó a legutoljára beolvasott sorszámot tárolja, a mymove egész változóban pedig a kiírandó sorszámnak kell lennie.

Ha C++ nyelven az iostreams modult használod, a következőképpen olvass, illetve írj:

cout<<mymove<<endl<<flush;
cin>>last;
Ha C vagy C++ nyelven a scanf és printf eljárásokat használod, a következőképpen olvass, illetve írj:
printf("%d\n",mymove); fflush (stdout);
scanf ("%d", &last);
Pascal nyelven a következőképpen olvass, illetve írj:
Writeln(mymove);
Readln(last);
Példa:
 
Az üregek és tálkák tartalma a lépés után
Lépés/üreg száma 1. 2. 3. 4. 5. 6. 7. Tálka1 Tálka2
Kezdőállapot 4 3 2 4 2 3 2 0 0
1. játékos lépése: 2 4 0 3 5 0 3 2 3 0
2. játékos lépése: 3 4 0 0 4 0 4 0 3 4
1. játékos lépése: 5 4 0 0 4 0 0 0 8 4
2. játékos lépése: 4 0 0 0 0 1 1 1 8 9
1. játékos lépése: 5 0 0 0 0 0 0 1 10 9
2. játékos lépése: 7 0 0 0 0 0 0 0 11 9
Pontozás:
Ha a programod nyer, 4 pontot, ha döntetlent ér el, 2 pontot, egyébként 0 pontot kapsz tesztesetenként.


Kettő-öt - 1. Nap, 3. feladat (100 pont, időlimit: 1 mp) /tesztadatok/
A Mikulás az ún. 25-nyelvet használja, amely az angol ábécé 25 betűjéből áll, A-tól Y-ig, a Z kivételével. Ebben a nyelvben minden szó pontosan 25 egymástól különböző betűből áll. A szavakat egy 5*5-ös mátrixba írjuk, sorfolytonosan. Például az ADJPTBEKQUCGLRVFINSWHMOXY szót így ábrázoljuk:
 
A D J P T
B E K Q U
C G L R V
F I N S W
H M O X Y

Csak azok a szavak helyesek a 25-nyelvben, amelyekben a betűk soronként és oszloponként egyaránt növekvő sorrendben fordulnak elő. Azaz helyes az ADJPTBEKQUCGLRVFINSWHMOXY szó és ezzel szemben hibás az ADJPTBEGQUCKLRVFINSWHMOXY szó (a második szóban a második és a harmadik oszlopban is rossz a betűk sorrendje).

A Mikulás szótárában az összes helyes szó ábécé szerint növekvő sorrendben van felsorolva és sorszámozva, a sorszám 1-től kezdődik. A szótárban az ABCDEFGHIJKLMNOPQRSTUVWXY az 1-es sorszámú szó, az ABCDEFGHIJKLMNOPQRSUTVWXY a 2-es sorszámú szó és így tovább. (A 2. szóban az U és a T helyet cserélt az 1. szóhoz képest.)

A Mikulás szótára meglehetősen nagy, de legfeljebb 231 szó van benne. Írj olyan programot, amely sorszámhoz szót, illetve szóhoz sorszámot rendel.

Bemenet:

A twofive.in állomány első sorában egy betű van: W vagy N. W esetén a második sorban a 25-nyelv egy szava, N esetén pedig egy szó sorszáma található.
Kimenet:
A twofive.out állományba egy sort kell kiírni: W esetén a megadott szó sorszá-mát, N esetén a megadott sorszámú szót 25-nyelven.
Példa:
twofive.in twofive.out
W
ABCDEFGHIJKLMNOPQRSUTVWXY
2
N
2
ABCDEFGHIJKLMNOPQRSUTVWXY