0884 - Paznici: Difference between revisions

From Bitnami MediaWiki
Pagină nouă: == Cerința == La o companie de securitate, paznicii trebuie să se alinieze pentru a-și primi instrucțiunile de patrulare. Fiecare paznic se adaugă în coadă pe măsură ce sosește sau poate părăsi coada dacă a primit deja instrucțiunile. Sarcina ta este să implementezi un program care să simuleze aceste operațiuni asupra unei cozi de paznici. == Date de intrare == Programul citește de la tastatură: Un număr întreg n reprezentând numărul de operațiuni. O...
 
No edit summary
Line 1: Line 1:
== Cerința ==
== Cerința ==
La o companie de securitate, paznicii trebuie să se alinieze pentru a-și primi instrucțiunile de patrulare. Fiecare paznic se adaugă în coadă pe măsură ce sosește sau poate părăsi coada dacă a primit deja instrucțiunile. Sarcina ta este să implementezi un program care să simuleze aceste operațiuni asupra unei cozi de paznici.
Se consideră o clădire de formă dreptunghiulară, formată din n*m camere dispuse sub forma unei matrice cu n linii și m coloane. Anumite camere sunt ocupate şi nu pot fi vizitate, celelalte sunt libere și pot fi vizitate. Dintr-o cameră se poate trece în altă cameră dacă ambele sunt libere și se învecinează pe linie sau pe coloană.
 
În anumite camere sunt paznici. Din motive de securitate, paznicii se pot deplasa din camera inițială în anumite camere libere din apropiere, dar fără a se îndepărta la o distanță mai mare decât o valoare cunoscută. Fiecare paznic va verifica periodic camerele libere în care poate ajunge.
 
Să se determine numărul de camere din clădire care nu sunt verificate de niciun paznic.
== Date de intrare ==
== Date de intrare ==
Programul citește de la tastatură:
Fișierul de intrare paznici.in conține pe prima linie trei numere n m p, reprezentând dimensiunile clădirii şi numărul de paznici.


Un număr întreg n reprezentând numărul de operațiuni.
Urmează n linii cu câte m caractere, care pot fi: -, reprezentând o cameră liberă, respectiv #, reprezentând o cameră ocupată.
O listă de n operațiuni, fiecare operațiune fiind de forma "ENQUEUE X" (unde X este numele unui paznic) sau "DEQUEUE".
 
Urmează p linii cu câte 3 valori i j d, reprezentând informaţiile despre paznici. i j reprezintă indicii camerei, iar d reprezintă distanţa pe care se poate deplasa acel paznic.
== Date de ieșire ==
== Date de ieșire ==
Pe ecran se va afișa coada rezultată după efectuarea tuturor operațiunilor. Dacă o operațiune "DEQUEUE" este efectuată pe o coadă goală, se va afișa mesajul "Eroare: coada goală".
Fișierul de ieșire paznici.out va conține pe prima linie numărul C de camere care nu sunt vizitate de niciun paznic.
== Restricții și precizări ==
== Restricții și precizări ==
*1 ⩽ '''n''' ⩽ 100
*1 n, m, p ≤ 200
* 'x' este întotdeauna un nume de paznic reprezentat printr-un șir de caractere
*1 ≤ i ≤ n
*1 ≤ j ≤ m
*0 ≤ d ≤ 40


== Exemplu 1 ==
== Exemplu 1 ==
;Intrare
;Intrare
5<br>
4 6 3<br>
ENQUEUE John<br>
--#-#-<br>
ENQUEUE Mike<br>
--##--<br>
DEQUEUE<br>
------<br>
ENQUEUE Anna<br>
-----#<br>
ENQUEUE Lisa
1 1 1<br>
1 6 2<br>
4 1 3


;Iesire
;Iesire
['Mike', 'Anna', 'Lisa']
4


== Exemplu 2 ==
== Exemplu 2 ==
Line 39: Line 48:
== Rezolvare ==
== Rezolvare ==
<syntaxhighlight lang="python" line>
<syntaxhighlight lang="python" line>
def citeste_date():
def in_bounds(x, y, n, m):
     try:
     return 0 <= x < n and 0 <= y < m
        n = int(input("Introduceți numărul de operațiuni (n): "))
        operatiuni = []
        for _ in range(n):
            operatiune = input().strip()
            operatiuni.append(operatiune)
        return n, operatiuni
    except ValueError:
        return None, None


def valideaza_date(n, operatiuni):
def mark_guard_reachable(grid, visited, x, y, d, n, m):
     if not (1 <= n <= 100):
     directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]  # N, S, W, E
        return False
    queue = [(x, y, 0)]
    for operatiune in operatiuni:
     visited[x][y] = True
        if not (operatiune.startswith("ENQUEUE ") or operatiune == "DEQUEUE"):
            return False
        if operatiune.startswith("ENQUEUE ") and len(operatiune.split()) != 2:
            return False
        if operatiune.startswith("ENQUEUE ") and not operatiune.split()[1].isalpha():
            return False
     return True


def proceseaza_operatiuni(n, operatiuni):
     while queue:
     coada = []
         cx, cy, dist = queue.pop(0)
    for operatiune in operatiuni:
        if dist < d:
         if operatiune.startswith("ENQUEUE "):
             for dx, dy in directions:
             _, nume = operatiune.split()
                nx, ny = cx + dx, cy + dy
            coada.append(nume)
                if in_bounds(nx, ny, n, m) and not visited[nx][ny] and grid[nx][ny] == '-':
        elif operatiune == "DEQUEUE":
                    visited[nx][ny] = True
            if coada:
                    queue.append((nx, ny, dist + 1))
                coada.pop(0)
            else:
                print("Eroare: coada goală")
    return coada


def main():
def main():
     n, operatiuni = citeste_date()
     with open("paznici.in", "r") as f:
   
        n, m, p = map(int, f.readline().strip().split())
     if n is None or operatiuni is None or not valideaza_date(n, operatiuni):
        grid = [list(f.readline().strip()) for _ in range(n)]
         print("Datele de intrare nu corespund restricțiilor impuse.")
        guards = [tuple(map(int, f.readline().strip().split())) for _ in range(p)]
        return
 
      
     visited = [[False for _ in range(m)] for _ in range(n)]
     print("Datele de intrare corespund restricțiilor impuse.")
 
    rezultat = proceseaza_operatiuni(n, operatiuni)
    for guard in guards:
     print(rezultat)
         i, j, d = guard
        mark_guard_reachable(grid, visited, i - 1, j - 1, d, n, m)
 
     unvisited_count = sum(1 for i in range(n) for j in range(m) if grid[i][j] == '-' and not visited[i][j])
 
     with open("paznici.out", "w") as f:
        f.write(f"{unvisited_count}\n")
 
if __name__ == "__main__":
     main()
 


if __name__ == "__main__":
if __name__ == "__main__":

Revision as of 23:34, 2 June 2024

Cerința

Se consideră o clădire de formă dreptunghiulară, formată din n*m camere dispuse sub forma unei matrice cu n linii și m coloane. Anumite camere sunt ocupate şi nu pot fi vizitate, celelalte sunt libere și pot fi vizitate. Dintr-o cameră se poate trece în altă cameră dacă ambele sunt libere și se învecinează pe linie sau pe coloană.

În anumite camere sunt paznici. Din motive de securitate, paznicii se pot deplasa din camera inițială în anumite camere libere din apropiere, dar fără a se îndepărta la o distanță mai mare decât o valoare cunoscută. Fiecare paznic va verifica periodic camerele libere în care poate ajunge.

Să se determine numărul de camere din clădire care nu sunt verificate de niciun paznic.

Date de intrare

Fișierul de intrare paznici.in conține pe prima linie trei numere n m p, reprezentând dimensiunile clădirii şi numărul de paznici.

Urmează n linii cu câte m caractere, care pot fi: -, reprezentând o cameră liberă, respectiv #, reprezentând o cameră ocupată.

Urmează p linii cu câte 3 valori i j d, reprezentând informaţiile despre paznici. i j reprezintă indicii camerei, iar d reprezintă distanţa pe care se poate deplasa acel paznic.

Date de ieșire

Fișierul de ieșire paznici.out va conține pe prima linie numărul C de camere care nu sunt vizitate de niciun paznic.

Restricții și precizări

  • 1 ≤ n, m, p ≤ 200
  • 1 ≤ i ≤ n
  • 1 ≤ j ≤ m
  • 0 ≤ d ≤ 40

Exemplu 1

Intrare

4 6 3
--#-#-
--##--




#

1 1 1
1 6 2
4 1 3

Iesire

4

Exemplu 2

Intrare

4
ENQUEUE George
DEQUEUE
DEQUEUE
ENQUEUE Paul

Iesire

Eroare: coada goală ['Paul']

Datele de intrare nu corespund restricțiilor impuse.

Rezolvare

<syntaxhighlight lang="python" line> def in_bounds(x, y, n, m):

   return 0 <= x < n and 0 <= y < m

def mark_guard_reachable(grid, visited, x, y, d, n, m):

   directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]  # N, S, W, E
   queue = [(x, y, 0)]
   visited[x][y] = True
   while queue:
       cx, cy, dist = queue.pop(0)
       if dist < d:
           for dx, dy in directions:
               nx, ny = cx + dx, cy + dy
               if in_bounds(nx, ny, n, m) and not visited[nx][ny] and grid[nx][ny] == '-':
                   visited[nx][ny] = True
                   queue.append((nx, ny, dist + 1))

def main():

   with open("paznici.in", "r") as f:
       n, m, p = map(int, f.readline().strip().split())
       grid = [list(f.readline().strip()) for _ in range(n)]
       guards = [tuple(map(int, f.readline().strip().split())) for _ in range(p)]
   visited = [[False for _ in range(m)] for _ in range(n)]
   for guard in guards:
       i, j, d = guard
       mark_guard_reachable(grid, visited, i - 1, j - 1, d, n, m)
   unvisited_count = sum(1 for i in range(n) for j in range(m) if grid[i][j] == '-' and not visited[i][j])
   with open("paznici.out", "w") as f:
       f.write(f"{unvisited_count}\n")

if __name__ == "__main__":

   main()


if __name__ == "__main__":

   main()

</syntaxhighlight>