3573 - Joc 11
Enunt
Pentru un concurs de design de jocuri, Gigel vrea să construiască un joc. La joc participă n concurenţi numerotaţi de la 1 la n. Fiecare concurent are la dispoziţie câte un şir de m încăperi, numerotate de la 1 la m. Scopul jocului este de a găsi o comoară ascunsă în una din aceste încăperi. Fiecare încăpere conţine un cod, număr natural, fie egal cu 0, fie având cel puţin 2 cifre. Ultima cifră indică numărul de etape de penalizare, adică numărul de etape în care concurentul nu are voie să părăsească încăperea. Numărul obţinut prin eliminarea ultimei cifre a codului indică numărul încăperii în care se va deplasa acesta la următoarea etapă sau la expirarea penalizării.
Există două excepţii de la regula de definire a codului: numărul 9999 codifică o încăpere conţinând o comoară, iar numărul 0 o încăpere conţinând o capcana.
În etapa 1 fiecare jucător intră în încăperea 1 din şirul său de încăperi. În funcţie de codul găsit în încăpere sunt posibile următoarele situaţii:
- codul găsit este 9999 ceea ce înseamnă că jucătorul este câştigător şi jocul se încheie la finalul acestei etape;
- codul găsit este 0 ceea ce duce la eliminarea sa din joc;
- pentru celelalte coduri, după efectuarea etapelor de penalizare, jucătorul efectuează o deplasare în încăperea indicată de cod. De exemplu la întâlnirea codul 157, după efectuarea celor 7 etape de penalizare jucătorul se va deplasa în camera 15.
Trecerea de la o etapă la alta se realizează simultan pentru toţi concurenţii.
Cerinţa
Fiind dat numărul n de concurenţi, numărul m de încăperi alocate fiecărui concurent, şi codurile din cele n×m încăperi să se determine câştigătorul jocului, numărul încăperii în care a găsit comoara, numărul de etape parcurse până când câştigătorul găseşte comoara precum şi numărul de concurenţi eliminaţi din joc până la etapa respectivă (inclusiv).
Date de intrare
Prima linie a fişierului de intrare joc11.in conţine două numere naturale n şi m, separate printr-un spaţiu, reprezentând numărul concurenţilor, respectiv numărul încăperilor. Următoarele n linii conţin câte m numere naturale, separate prin câte un spaţiu, reprezentând codurile din fiecare încăpere.
Date de ieșire
Prima linie a fişierului de ieşire joc11.out va conţine patru numere naturale separate prin câte un spaţiu, reprezentând indicele câştigătorului, numărul încăperii unde a găsit comoara, numărul etapei în care a câştigat şi respectiv numărul de concurenţi eliminaţi din joc.
Restricţii şi precizări
- 1 ≤ n ≤ 400
- 1 ≤ m ≤ 900
- Pentru toate testele de intrare se garantează că există exact un câştigător.
Exemplu
- joc11.in
4 8 0 9999 41 50 61 70 80 30 30 80 60 60 9999 21 40 50 20 30 40 50 61 71 81 9999 20 30 50 0 61 71 9999 41
- joc11.out
2 5 7 1
Explicație
Câştigă jucătorul al 2-lea, după 7 etape, iar încăperea în care a găsit comoara este încăperea 5. În cele 7 etape a fost eliminat un singur concurent şi anume primul concurent. Încăperile prin care trece jucătorul câştigător până la final sunt: 1->3->6->2->8->5
Rezolvare
<syntaxhighlight lang="python" line> def simulate_game(n, m, rooms):
winner = None room_number = None steps = 0 eliminated = 0
# Cream o listă de seturi pentru a memora concurenții eliminați în fiecare etapă eliminated_each_step = [set() for _ in range(m)]
for step in range(m): next_rooms = [0] * n # Inițializăm lista cu următoarele încăperi pentru fiecare concurent for i in range(n): if i in eliminated_each_step[step]: continue # Dacă concurentul este deja eliminat în această etapă, nu facem nimic cu el
code = rooms[i][step] # Codul din încăperea curentă a concurentului
if code == 9999: winner = i + 1 room_number = step + 1 steps = step + 1 return winner, room_number, steps, eliminated
if code == 0: eliminated += 1 eliminated_each_step[step].add(i) else: next_room = int(str(code)[:-1]) # Obținem numărul următoarei încăperi next_rooms[next_room - 1] += 1
# Actualizăm seturile de concurenți eliminați pentru etapele următoare for i in range(n): if next_rooms[i] > 1: eliminated_each_step[step + 1].add(i)
return winner, room_number, steps, eliminated
def main():
with open("joc11.in", "r") as fin: n, m = map(int, fin.readline().split()) rooms = [list(map(int, fin.readline().split())) for _ in range(n)]
winner, room_number, steps, eliminated = simulate_game(n, m, rooms)
with open("joc11.out", "w") as fout: fout.write(f"{winner} {room_number} {steps} {eliminated}\n")
if __name__ == "__main__":
main()
</syntaxhighlight>