Nu mai stiu cand are problema 22 deadline-ul, dar o trimit oricum
pe a 23-a.
PROBLEMA 23: NIM
DEADLINE: Miercuri, 23 iunie
TIMP DE IMPLEMENTARE: O ora
DOMENIU: Joc logic
PUNCTAJ: 40 dexteri
Multumiri pentru ideea acestei probleme (si probabil si a urmatoarei
probleme :) ) fratelui meu Cristi (se aude???)
Jocul NIM este arhicunoscut: Se dau N gramezi de pietre (1<=N<=100). In
gramada i se afla P[i] pietre, 1<=i<=N, 1<=P[i]<=100. Doi jucatori
efectueaza pe rand mutari. O mutare consta din eliminarea oricator pietre,
cu conditia ca ele sa fie din aceeasi gramada. Cel care elimina ultima
piatra castiga jocul. Se cere sa scrieti un program care:
1) Joaca NIM, fiind mereu primul la mutare;
2) Incearca sa bata modulul care vi se va pune la dispozitie, despre care
va promit ca joaca perfect (adica daca are ocazia sa bata programul vostru,
il va bate);
Se garanteaza ca din configuratia initiala programul vostru poate castiga
intotdeauna, daca stie cum.
Un exemplu de joc NIM cu trei gramezi poate fi:
Initial, continutul gramezilor este
2 1 3
J1 ia 2 pietre din gramada 3:
2 1 1
J2 ia 2 pietre din gramada 1:
0 1 1
J1 ia o piatra din gramada 3:
0 1 0
J2 ia o piatra din gramada 2 si castiga.
Modulul care va fi partenerul programului vostru se numeste NIM.TPU (pentru
pascalisti) respectiv NIM.H (pentru siisti) si furnizeaza rutinele:
Pascal: procedure m_start;
C: void m_start(void);
Initializeaza jocul. Trebuie apelata o singura data, inaintea oricaror alte
rutine din modul.
Pascal: function m_heapcount:Integer;
C: int m_heapcount(void);
Intoarce numarul de gramezi. O puteti apela de cate ori doriti.
Pascal: function m_piececount(heap:Integer):Integer;
C: int m_piececount(int heap);
Intoarce numarul de pietre aflate in momentul apelului in gramada "heap".
Daca "heap" nu se afla intre 1 si m_heapcount(), m_piececount() intoarce 0.
Pascal: procedure m_mymove(heap, count:Integer);
C: void m_mymove(int heap, int count);
Efectueaza o mutare a voastra (ia "count" pietre din gramada "heap"). Daca
"heap" nu se afla intre 1 si m_heapcount() sau daca (scuzati) "count" nu
se afla intre 1 si m_piececount(heap), modulul intoarce eroare si pierdeti
testul (si in plus sunteti trimisi la colt pana la sfarsitul orei).
Pascal: procedure m_modulemove(var heap, count:Integer);
C: void m_modulemove(int *heap, int *count);
Intoarce mutarea pe care doreste sa o faca modulul (gramada si numarul de
piese). Modulul NU va trisa :)
Nu este nevoie sa opriti in nici un fel programul. Modulul isi da singur
seama cand ultima piesa a fost ridicata si opreste programul.
Dupa cum se spune la TOEFL, "any attempt to tamper with the computer will
have you eliminated from the contest" :) Asta include apelul mutarilor in
alta ordine decat Eu-Modulul-Eu-Modulul..., omiterea apelului lui m_start(),
repetarea apelului lui m_start() s.a.m.d.
Timp de rulare permis per test: Doua secunde. Timpul necesar pentru
- una bucata apel al rutinei m_start() SI
- una bucata apel al rutinei m_heapcount() SI
- 100 de apeluri ale rutinei m_piececount() SI
- 5000 de apeluri ale rutinei m_mymove() SI
- 5000 de apeluri ale rutinei m_modulemove()
nu va depasi o secunda. Variabilele modulului nu depasesc 1KB.
Succes!
Atasez un modul demonstrativ, care nu respecta regula promisa, adica daca
are ocazia sa va bata, nu va bate neaparat:)
|
|