3949 - mindist: Difference between revisions

From Bitnami MediaWiki
Pagină nouă: ==Cerința== MăcGregăr se află într-o matrice pătratică cu '''N''' linii și '''N''' coloane. Aflându-se în celula '''(i, j)''' acesta se poate deplasa printr-un pas într-una din celulele '''(i + 1, j), (i, j + 1), (i - 1, j), (i, j - 1)'''. Sunt '''M''' celule distincte prin care el nu poate trece, deoarece sunt ocupate cu echipamentul lui sportiv. De asemenea, mai sunt '''K''' celule distincte, diferite de cele ocupate, în care se află proteina lui MăcGregăr....
 
No edit summary
 
Line 5: Line 5:
==Date de intrare==
==Date de intrare==


Fișierul de intrare '''mindist.in''' conține pe prima linie numerele '''N''', '''M''' și '''K''' separate printr-un spațiu. Pe următoarele '''M''' linii se află câte două numere naturale reprezentând linia și coloana pe care se află o celulă ocupată. Pe următoarele '''K''' linii se află câte două numere naturale reprezentând linia și coloana pe care se află o proteină.
Fișierul de intrare '''mindistin.txt''' conține pe prima linie numerele '''N''', '''M''' și '''K''' separate printr-un spațiu. Pe următoarele '''M''' linii se află câte două numere naturale reprezentând linia și coloana pe care se află o celulă ocupată. Pe următoarele '''K''' linii se află câte două numere naturale reprezentând linia și coloana pe care se află o proteină.


==Date de ieșire==
==Date de ieșire==


Fișierul de ieșire '''mindist.out''' va conține '''N''' linii, fiecare linie va conține '''N''' numere întregi, separate printr-un spațiu. Pe linia '''i''', a '''j'''-a valoare reprezintă numărul minim de pași pentru a ajunge din celula '''(i, j)''' la cea mai apropiată proteină, dacă un astfel de drum există, '''-1''' altfel.
Fișierul de ieșire '''mindistout.txt''' va conține '''N''' linii, fiecare linie va conține '''N''' numere întregi, separate printr-un spațiu. Pe linia '''i''', a '''j'''-a valoare reprezintă numărul minim de pași pentru a ajunge din celula '''(i, j)''' la cea mai apropiată proteină, dacă un astfel de drum există, '''-1''' altfel.


==Restricții și precizări==
==Restricții și precizări==
Line 19: Line 19:
*Pentru restul de 40p, avem '''1 ≤ N ≤ 1000'''
*Pentru restul de 40p, avem '''1 ≤ N ≤ 1000'''


==Exemplu:==
==Exemplul 1:==


'''mindist.in'''
'''mindistin.txt'''


:4 5 3
4 5 3
:4 3
4 3
:2 1
2 1
:4 2
4 2
:4 1
4 1
:3 4
3 4
:3 3
3 3
:2 3
2 3
:1 1
1 1


'''mindist.out'''
'''mindistout.txt'''


:0 1 1 2  
Datele de intrare corespund restrictiilor impuse
:-1 1 0 1  
0 1 1 2  
:2 1 0 -1  
-1 1 0 1  
:-1 -1 -1 -1  
2 1 0 -1  
-1 -1 -1 -1  
 
==Exemplul 2:==
 
'''mindistin.txt'''
 
51
 
'''mindistout.txt'''
 
Datele de intrare nu corespund restrictiilor impuse


==Rezolvare==
==Rezolvare==
Line 46: Line 57:
from collections import deque
from collections import deque


def mindist(N, M, K, blocked, proteins):
 
    # Definim directiile in care se poate deplasa MacGregor
def validare(numar_n, numar_m, numar_k):  # functia de validare a datelor de intrare
    if numar_n < 1 or numar_n > 1000 or numar_m < 1 or numar_m > numar_n*numar_n or numar_k < 1 or numar_k > n*n:
        raise ValueError
    file_out.write("Datele de intrare corespund restrictiilor impuse\n")
 
 
def mindist(numar_n, blocked, proteins): # functia de rezolvare
     dx = [-1, 0, 1, 0]
     dx = [-1, 0, 1, 0]
     dy = [0, 1, 0, -1]
     dy = [0, 1, 0, -1]
 
     matrix = [[-1 for _ in range(numar_n)] for _ in range(numar_n)]
    # Initializam matricea cu -1
     matrix = [[-1 for _ in range(N)] for _ in range(N)]
 
    # Initializam coada pentru BFS
     queue = deque()
     queue = deque()
    # Marcam celulele blocate cu -2
     for b in blocked:
     for b in blocked:
         matrix[b[0]-1][b[1]-1] = -2
         matrix[b[0]-1][b[1]-1] = -2
    # Adaugam proteinele in coada si le marcam cu 0 in matrice
     for p in proteins:
     for p in proteins:
         queue.append((p[0]-1, p[1]-1))
         queue.append((p[0]-1, p[1]-1))
         matrix[p[0]-1][p[1]-1] = 0
         matrix[p[0]-1][p[1]-1] = 0
    # Parcurgem coada
     while queue:
     while queue:
         x, y = queue.popleft()
         x, y = queue.popleft()
        # Incercam sa ne deplasam in toate directiile
         for i in range(4):
         for i in range(4):
             nx, ny = x + dx[i], y + dy[i]
             nx, ny = x + dx[i], y + dy[i]
            # Verificam daca noua pozitie este valida si nevizitata
             if 0 <= nx < numar_n and 0 <= ny < numar_n and matrix[nx][ny] == -1:
             if nx >= 0 and nx < N and ny >= 0 and ny < N and matrix[nx][ny] == -1:
                # Actualizam distanta si adaugam pozitia in coada
                 matrix[nx][ny] = matrix[x][y] + 1
                 matrix[nx][ny] = matrix[x][y] + 1
                 queue.append((nx, ny))
                 queue.append((nx, ny))
     return matrix
     return matrix


# Datele de intrare
N = 4
M = 5
K = 3
blocked = [(4, 3), (2, 1), (4, 2), (4, 1), (3, 4)]
proteins = [(3, 3), (2, 3), (1, 1)]
# Apelam functia
result = mindist(N, M, K, blocked, proteins)


# Scriem rezultatul in fisier
if __name__ == '__main__':
with open('mindist.out', 'w') as f:
    try:
    for row in result:
        file_in = open("mindistin.txt", "r")        # declararea fisierelor
        f.write(' '.join(str(x) if x != -2 else '-1' for x in row))
        file_out = open("mindistout.txt", "w")      # fisierul out trebuie declarat cu optiunea "w" (write)
        f.write('\n')
        n, m, k = map(int, file_in.readline().split())
        blocat = [tuple(map(int, file_in.readline().split())) for _ in range(m)]
        proteine = [tuple(map(int, file_in.readline().split())) for _ in range(k)]
        validare(n, m, k)
        result = mindist(n, blocat, proteine)
        for row in result:
            file_out.write(' '.join(str(x) if x != -2 else '-1' for x in row))
            file_out.write('\n')
    except ValueError:
        file_out.write("Datele de intrare nu corespund restrictiilor impuse\n")
    except IndexError:
        file_out.write("Datele de intrare nu corespund restrictiilor impuse\n")


</syntaxhighlight>
</syntaxhighlight>

Latest revision as of 19:54, 15 November 2023

Cerința[edit | edit source]

MăcGregăr se află într-o matrice pătratică cu N linii și N coloane. Aflându-se în celula (i, j) acesta se poate deplasa printr-un pas într-una din celulele (i + 1, j), (i, j + 1), (i - 1, j), (i, j - 1). Sunt M celule distincte prin care el nu poate trece, deoarece sunt ocupate cu echipamentul lui sportiv. De asemenea, mai sunt K celule distincte, diferite de cele ocupate, în care se află proteina lui MăcGregăr. Pentru fiecare celulă din matrice din care acesta ar pleca, MăcGregăr se întreabă care este numărul minim de pași pentru a ajunge la cea mai apropiată proteină.

Date de intrare[edit | edit source]

Fișierul de intrare mindistin.txt conține pe prima linie numerele N, M și K separate printr-un spațiu. Pe următoarele M linii se află câte două numere naturale reprezentând linia și coloana pe care se află o celulă ocupată. Pe următoarele K linii se află câte două numere naturale reprezentând linia și coloana pe care se află o proteină.

Date de ieșire[edit | edit source]

Fișierul de ieșire mindistout.txt va conține N linii, fiecare linie va conține N numere întregi, separate printr-un spațiu. Pe linia i, a j-a valoare reprezintă numărul minim de pași pentru a ajunge din celula (i, j) la cea mai apropiată proteină, dacă un astfel de drum există, -1 altfel.

Restricții și precizări[edit | edit source]

  • 1 ≤ M ≤ N * N
  • 1 ≤ K ≤ N * N
  • Pentru 30p, avem 1 ≤ N ≤ 50
  • Pentru alte 30p, avem 1 ≤ N ≤ 1000 și 1 ≤ K ≤ 10
  • Pentru restul de 40p, avem 1 ≤ N ≤ 1000

Exemplul 1:[edit | edit source]

mindistin.txt

4 5 3
4 3
2 1
4 2
4 1
3 4
3 3
2 3
1 1

mindistout.txt

Datele de intrare corespund restrictiilor impuse
0 1 1 2 
-1 1 0 1 
2 1 0 -1 
-1 -1 -1 -1 

Exemplul 2:[edit | edit source]

mindistin.txt

51

mindistout.txt

Datele de intrare nu corespund restrictiilor impuse

Rezolvare[edit | edit source]

<syntaxhighlight lang="python" line="1" start="1">

from collections import deque


def validare(numar_n, numar_m, numar_k): # functia de validare a datelor de intrare

   if numar_n < 1 or numar_n > 1000 or numar_m < 1 or numar_m > numar_n*numar_n or numar_k < 1 or numar_k > n*n:
       raise ValueError
   file_out.write("Datele de intrare corespund restrictiilor impuse\n")


def mindist(numar_n, blocked, proteins): # functia de rezolvare

   dx = [-1, 0, 1, 0]
   dy = [0, 1, 0, -1]
   matrix = [[-1 for _ in range(numar_n)] for _ in range(numar_n)]
   queue = deque()
   for b in blocked:
       matrix[b[0]-1][b[1]-1] = -2
   for p in proteins:
       queue.append((p[0]-1, p[1]-1))
       matrix[p[0]-1][p[1]-1] = 0
   while queue:
       x, y = queue.popleft()
       for i in range(4):
           nx, ny = x + dx[i], y + dy[i]
           if 0 <= nx < numar_n and 0 <= ny < numar_n and matrix[nx][ny] == -1:
               matrix[nx][ny] = matrix[x][y] + 1
               queue.append((nx, ny))
   return matrix


if __name__ == '__main__':

   try:
       file_in = open("mindistin.txt", "r")         # declararea fisierelor
       file_out = open("mindistout.txt", "w")       # fisierul out trebuie declarat cu optiunea "w" (write)
       n, m, k = map(int, file_in.readline().split())
       blocat = [tuple(map(int, file_in.readline().split())) for _ in range(m)]
       proteine = [tuple(map(int, file_in.readline().split())) for _ in range(k)]
       validare(n, m, k)
       result = mindist(n, blocat, proteine)
       for row in result:
           file_out.write(' '.join(str(x) if x != -2 else '-1' for x in row))
           file_out.write('\n')
   except ValueError:
       file_out.write("Datele de intrare nu corespund restrictiilor impuse\n")
   except IndexError:
       file_out.write("Datele de intrare nu corespund restrictiilor impuse\n")

</syntaxhighlight>