0864 - Roboti

From Bitnami MediaWiki

Cerința[edit | edit source]

Se dă o matrice cu n linii și m coloane și elemente 0 sau 1, reprezentând planul unui teren în care 0 reprezintă o zonă accesibilă, iar 1 reprezintă o zonă inaccesibilă. O zonă a terenului are ca și coordonate linia și coloana corespunzătoare din matrice. Într-o zonă cunoscută a matricei se află un robot, iar în altă zonă, de asemenea cunoscută, se află o roboțică. Determinați numărul minim de pași prin care robotul va ajunge la roboțică. Dacă nu este posibil ca robotul să ajungă la roboțică, rezultatul va fi -1.

Date de intrare[edit | edit source]

Fișierul de intrare robotiin.txt conține pe prima linie numerele n m. Următoarele n linii conțin câte m valori, 0 sau 1. Următoarele două linii conțin câte două valori, reprezentând coordonatele robotului, respectiv ale roboțicii.

Date de ieșire[edit | edit source]

Fișierul de ieșire robotiout.txt va conține pe prima linie valoarea cerută.

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

  • 1 ≤ n , m ≤ 1000
  • zonele pe care se află inițial cei doi roboți sunt libere și sunt diferite
  • un pas reprezintă trecerea robotului din zona curentă într-o zonă vecină cu aceasta pe linie sau pe coloană, fără a părăsi matricea.

Exemplul 1:[edit | edit source]

robotiin.txt
4 5
1 0 0 0 1
0 0 1 0 0
0 0 0 0 1
1 1 0 0 1
1 2
2 5
robotiout.txt
Datele de intrare corespund restrictiilor impuse
4

Exemplul 2:[edit | edit source]

robotiin.txt
robot
robotiout.txt
Datele de intrare nu corespund restrictiilor impuse

Explicație[edit | edit source]

Un traseu al robotului format din 4 pași este evidențiat mai jos.

1 0 0 0 1 0 0 1 0 0 0 0 0 0 1 1 1 0 0 1 Există și alte trasee posibile, dar lungimea lor este mai mare.

Rezolvare[edit | edit source]

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

from collections import deque


def validare(nr_n, nr_m, matrix, x_inceput, y_inceput, x_sfarsit, y_sfarsit, fisier_out):

   if not (1 <= nr_n <= 1000 and 1 <= nr_m <= 1000):
       raise ValueError
   for linie in matrix:
       for elem in linie:
           if not isinstance(elem, int):
               raise ValueError
   if not (0 <= x_inceput < nr_n and 0 <= y_inceput < nr_m and 0 <= x_sfarsit < nr_n and 0 <= y_sfarsit < nr_m):
       raise ValueError
   if matrix[x_inceput][y_inceput] != 0 or matrix[x_sfarsit][y_sfarsit] != 0 or (x_inceput == x_sfarsit and y_inceput == y_sfarsit):
       raise ValueError
   fisier_out.write("Datele de intrare corespund restrictiilor impuse\n")


def bfs(nr_n, nr_m, matrix, x_inceput, y_inceput, x_sfarsit, y_sfarsit):

   dx = [-1, 0, 1, 0]
   dy = [0, 1, 0, -1]
   distanta = [[-1 for _ in range(nr_m)] for _ in range(nr_n)]
   coada = deque()
   coada.append((x_inceput, y_inceput))
   distanta[x_inceput][y_inceput] = 0
   while coada:
       x, y = coada.popleft()
       for directie in range(4):
           new_x, new_y = x + dx[directie], y + dy[directie]
           if 0 <= new_x < nr_n and 0 <= new_y < nr_m and matrix[new_x][new_y] == 0 and distanta[new_x][new_y] == -1:
               coada.append((new_x, new_y))
               distanta[new_x][new_y] = distanta[x][y] + 1
   return distanta[x_sfarsit][y_sfarsit]


if __name__ == "__main__":

   file_in = open('robotiin.txt', 'r')
   file_out = open('robotiout.txt', 'w')
   try:
       n, m = map(int, file_in.readline().split())
       matrice = [list(map(int, file_in.readline().split())) for _ in range(n)]
       x_start, y_start = map(int, file_in.readline().split())
       x_end, y_end = map(int, file_in.readline().split())
       validare(n, m, matrice, x_start-1, y_start-1, x_end-1, y_end-1, file_out)
       rezultat = bfs(n, m, matrice, x_start-1, y_start-1, x_end-1, y_end-1)
       file_out.write(str(rezultat))
   except ValueError:
       file_out.write("Datele de intrare nu corespund restrictiilor impuse")
   except IndexError:
       file_out.write("Datele de intrare nu corespund restrictiilor impuse")

</syntaxhighlight>