1275 - Jaina: Diferență între versiuni

De la Universitas MediaWiki
(Pagină nouă: == Cerinta == Jaina se află în Theramore Isle și trebuie să ajungă la mentorul ei, Antonidas. Aceștia se află într-o matrice pătratică de dimensiune n x n, în poziții de coordonate cunoscute. Jaina se poate deplasa în oricare dintre cele 8 direcții. Astfel, dacă inițial ea se găsește în celula de coordonate (x, y), poate ajunge în oricare dintre celulele (x-1, y-1), (x-1, y), (x-1, y + 1), (x, y + 1), (x + 1, y + 1), (x + 1, y), (x + 1, y - 1) sau (x, y...)
 
Fără descriere a modificării
 
Linia 1: Linia 1:
== Cerinta ==
== Cerinta ==


Jaina se află în Theramore Isle și trebuie să ajungă la mentorul ei, Antonidas. Aceștia se află într-o matrice pătratică de dimensiune n x n, în poziții de coordonate cunoscute.
Jaina se află în Theramore Isle și trebuie să ajungă la mentorul ei, Antonidas. Aceștia se află într-o matrice pătratică de dimensiune <code>n x n</code>, în poziții de coordonate cunoscute.


Jaina se poate deplasa în oricare dintre cele 8 direcții. Astfel, dacă inițial ea se găsește în celula de coordonate (x, y), poate ajunge în oricare dintre celulele (x-1, y-1), (x-1, y), (x-1, y + 1), (x, y + 1), (x + 1, y + 1), (x + 1, y), (x + 1, y - 1) sau (x, y - 1) făcând exact un pas.
Jaina se poate deplasa în oricare dintre cele <code>8</code> direcții. Astfel, dacă inițial ea se găsește în celula de coordonate <code>(x, y)</code>, poate ajunge în oricare dintre celulele <code>(x-1, y-1)</code>, <code>(x-1, y)</code>, <code>(x-1, y + 1)</code>, <code>(x, y + 1)</code>, <code>(x + 1, y + 1)</code>, <code>(x + 1, y)</code>, <code>(x + 1, y - 1)</code> sau <code>(x, y - 1)</code> făcând exact un pas.
În anumite celule se află câte o sursă de energie. Fiecare sursă emite raze în patru direcții (N, E, S, V), fiecare rază ajungând până la marginea matricei.
 
În anumite celule se află câte o sursă de energie. Fiecare sursă emite raze în patru direcții <code>(N, E, S, V)</code>, fiecare rază ajungând până la marginea matricei.


Când Jaina pășește pe o astfel de rază, ea se teleportează obligatoriu în celula sursei razei respective, deci nu este posibilă trecerea dincolo de aceste raze decât prin punctul sursă. Teleportarea este automată și instantanee și nu se consideră ca fiind un pas al Jainei.
Când Jaina pășește pe o astfel de rază, ea se teleportează obligatoriu în celula sursei razei respective, deci nu este posibilă trecerea dincolo de aceste raze decât prin punctul sursă. Teleportarea este automată și instantanee și nu se consideră ca fiind un pas al Jainei.
Linia 10: Linia 11:
Antonidas vă roagă să o ajutați pe Jaina să ajungă la el, efectuând un număr minim de pași!
Antonidas vă roagă să o ajutați pe Jaina să ajungă la el, efectuând un număr minim de pași!


== Date de intrare ==
= Date de intrare =
Fișierul de intrare <code>jainaIN.txt</code> conține pe prima linie numărul <code>n</code>, iar pe a doua linie <code>4</code> numere naturale separate prin spații, care semnifică coordonatele celulei în care se află Jaina și coordonatele celulei în care se află Antonidas. ( 2 perechi linie-coloană )


Fișierul de intrare jaina.in conține pe prima linie numărul n, iar pe a doua linie 4 numere naturale separate prin spații, care semnifică coordonatele celulei în care se află Jaina și coordonatele celulei în care se află Antonidas. ( 2 perechi linie-coloană )
A treia linie conține numărul <code>m</code> de surse de energie.


A treia linie conține numărul m de surse de energie.
Pe următoarele <code>m</code> linii se află câte două numere naturale <code>x y</code>, reprezentând coordonatele fiecărei surse.


Pe următoarele m linii se află câte două numere naturale x y, reprezentând coordonatele fiecărei surse.
= Date de ieșire =
Fișierul de ieșire <code>jainaOUT.txt</code> va conține pe prima linie numărul <code>nrp</code>, reprezentând numărul minim de pași pe care Jaina trebuie să-i efectueze pentru a ajunge la Antonidas. În cazul în care restricțiile nu sunt îndeplinite, se va afișa mesajul "Datele nu corespund restrictiilor impuse".


== Date de iesire ==
= Restricții și precizări =


Fișierul de ieșire jaina.out va conține pe prima linie numărul nrp, reprezentând numărul minim de pași pe care Jaina trebuie -i efectueze pentru a ajunge la Antonidas.
* <code>1 ≤ n ≤ 100</code>
* <code>1 ≤ m ≤ 10</code>
* Orice celulă are dimensiunea <code>1x1</code>
* În cazul în care Jaina se află la intersecția a două raze de surse diferite, aceasta se va teleporta la sursa de linie minimă.
* Nu există două surse care să se afle pe aceeași linie sau pe aceeași coloană.
* Se garantează că există soluție pentru toate testele.
* Antonidas promite că o fiți răsplătiți cu o minge de foc dacă găsiți răspunsul corect la această problemă.
* Deoarece Jaina este disperată, limitele de memorie sunt foarte mari, însă pe viitor nu este garantat acest lucru!


== Restrictii si precizari ==
= Exemplul 1: =
<code>jainaIN.txt</code>
4
2 1 4 4
1
3 3
<code>jainaOUT.txt</code>
2


*1 ≤ n ≤ 100
=== Explicație ===
*1 ≤ m ≤ 10
Numărul de pași necesari în acest caz este 2.
*Orice celulă are dimensiunea 1x1
*În cazul în care Jaina se află la intersecția a două raze de surse diferite, aceasta se va teleporta la sursa de linie minimă.
*Nu există două surse care să se afle pe aceeași linie sau pe aceeași coloană.
*Se garantează că există soluție pentru toate testele.
*Antonidas promite că o să fiți răsplătiți cu o minge de foc dacă găsiți răspunsul corect la această problemă.
*Deoarece Jaina este disperată, limitele de memorie sunt foarte mari, însă pe viitor nu este garantat acest lucru!


== Exemplul 1 ==
= Exemplul 2: =
<code>jainaIN.txt</code>
4
2 1 4 4
1
3 3
<code>jainaOUT.txt</code>
Datele nu corespund restrictiilor impuse


;jainain.txt
== Rezolvare ==


:4
<syntaxhighlight lang="python3" line="1">
from collections import deque


:2 1 4 4
class Celula:
    def __init__(self):
        self.val = 0
        self.laser = 0
        self.xs = 0
        self.ys = 0


:1
nmax = 100
dl = [-1, -1, -1, 0, 1, 1, 1, 0]
dc = [-1, 0, 1, 1, 1, 0, -1, -1]


:3 3
def inside(x, y, n):
 
    return 1 <= x <= n and 1 <= y <= n
;jainaout.txt
 
:Datele introduse corespund restrictiilor impuse.
 
:2
 
== Exemplul 2 ==
 
;jainain.txt
 
:0
 
:-1 -2 -1 0
 
:0
 
:88 90
 
;jainaout.txt
 
:Datele de intrare nu corespund restrictiilor impuse.
 
== Rezolvare ==
 
<syntaxhighlight lang="python3" line="1">
 
from collections import deque


def gaseste_cale(matrice, start, destinatie):
def nord_sud(x, y, a, n):
     n = len(matrice)
     for i in range(1, n + 1):
        if a[i][y].laser == 0 and i != x:
            a[i][y].laser = 1
            a[i][y].xs = x
            a[i][y].ys = y
        elif i != x:
            if x < a[i][y].xs:
                a[i][y].xs = x
                a[i][y].ys = y


    # Direcțiile posibile pentru deplasare
def est_vest(x, y, a, n):
    directii = [(-1, 0), (0, 1), (1, 0), (0, -1), (-1, -1), (-1, 1), (1, 1), (1, -1)]
    for j in range(1, n + 1):
        if a[x][j].laser == 0 and j != y:
            a[x][j].laser = 1
            a[x][j].xs = x
            a[x][j].ys = y
        elif j != y:
            if x < a[x][j].xs:
                a[x][j].xs = x
                a[x][j].ys = y


     queue = deque([(start[0], start[1], 0)]) # Coada pentru BFS
def solve(n, xi, yi, xf, yf, m, a):
     vizitat = set([(start[0], start[1])])  # Set pentru a urmări celulele vizitate
     q = deque([(xi, yi)])
     a[xi][yi].val = 1


     while queue:
     while q:
         x, y, pasi = queue.popleft()
         f1, f2 = q.popleft()


         if (x, y) == destinatie:
         for k in range(8):
             return pasi  # Am ajuns la destinație
            iv = f1 + dl[k]
             jv = f2 + dc[k]


        for dx, dy in directii:
            if inside(iv, jv, n) and (not a[iv][jv].val or a[iv][jv].val > a[f1][f2].val + 1):
            nx, ny = x + dx, y + dy
                if a[iv][jv].laser == 0:
                    a[iv][jv].val = a[f1][f2].val + 1
                    q.append((iv, jv))
                else:
                    lin = a[iv][jv].xs
                    col = a[iv][jv].ys
                    a[iv][jv].val = a[f1][f2].val + 1


            if 0 <= nx < n and 0 <= ny < n and (nx, ny) not in vizitat:
                    if a[lin][col].val > a[iv][jv].val or not a[lin][col].val:
                # Verificăm dacă există o sursă de energie la noua poziție
                        a[lin][col].val = a[iv][jv].val
                if matrice[nx][ny] == 'S':
                        q.append((lin, col))
                    # Teleportăm instantaneu Jaina la sursa de energie
                        q.append((iv, jv))
                    nx, ny = start


                queue.append((nx, ny, pasi + 1))
    return a[xf][yf].val - 1
                vizitat.add((nx, ny))


     return -1 # Destinația nu poate fi atinsă
def verificare_restrictii(n, m):
     if not (1 <= n <= 100 and 1 <= m <= 10):
        with open("jainaOUT.txt", "w") as f:
            f.write("Datele nu corespund restrictiilor impuse")
        return False
    return True


# Exemplu de utilizare
def citire():
matrice = [
     with open("jainaIN.txt", "r") as f:
     ['.', '.', '.', '.', 'S', '.', '.', '.'],
        n = int(f.readline().strip())
    ['.', '.', '.', '.', '.', '.', '.', '.'],
        xi, yi, xf, yf = map(int, f.readline().split())
    ['.', 'S', '.', '.', '.', '.', '.', '.'],
        m = int(f.readline().strip())
    ['.', '.', '.', '.', '.', '.', '.', '.'],
        if not verificare_restrictii(n, m):
    ['.', '.', '.', '.', '.', '.', '.', '.'],
            exit()  # Ieșire din program dacă restricțiile nu sunt respectate
    ['.', '.', '.', '.', '.', '.', '.', '.'],
        a = [[Celula() for _ in range(nmax + 1)] for _ in range(nmax + 1)]
    ['.', '.', '.', '.', '.', '.', 'S', '.'],
        for _ in range(m):
     ['.', '.', '.', '.', '.', '.', '.', '.']
            x, y = map(int, f.readline().split())
]
            nord_sud(x, y, a, n)
            est_vest(x, y, a, n)
     return n, xi, yi, xf, yf, a


start = (0, 0)
def scriere(result):
destinatie = (7, 7)
    with open("jainaOUT.txt", "w") as f:
        f.write(str(result))


rezultat = gaseste_cale(matrice, start, destinatie)
def main():
    n, xi, yi, xf, yf, a = citire()
    result = solve(n, xi, yi, xf, yf, n, a)
    scriere(result)


if rezultat != -1:
if __name__ == "__main__":
    print(f"Numărul minim de pași necesari: {rezultat}")
     main()
else:
     print("Destinația nu poate fi atinsă.")


</syntaxhighlight>
</syntaxhighlight>

Versiunea curentă din 23 februarie 2024 07:07

Cerinta

Jaina se află în Theramore Isle și trebuie să ajungă la mentorul ei, Antonidas. Aceștia se află într-o matrice pătratică de dimensiune n x n, în poziții de coordonate cunoscute.

Jaina se poate deplasa în oricare dintre cele 8 direcții. Astfel, dacă inițial ea se găsește în celula de coordonate (x, y), poate ajunge în oricare dintre celulele (x-1, y-1), (x-1, y), (x-1, y + 1), (x, y + 1), (x + 1, y + 1), (x + 1, y), (x + 1, y - 1) sau (x, y - 1) făcând exact un pas.

În anumite celule se află câte o sursă de energie. Fiecare sursă emite raze în patru direcții (N, E, S, V), fiecare rază ajungând până la marginea matricei.

Când Jaina pășește pe o astfel de rază, ea se teleportează obligatoriu în celula sursei razei respective, deci nu este posibilă trecerea dincolo de aceste raze decât prin punctul sursă. Teleportarea este automată și instantanee și nu se consideră ca fiind un pas al Jainei.

Antonidas vă roagă să o ajutați pe Jaina să ajungă la el, efectuând un număr minim de pași!

Date de intrare

Fișierul de intrare jainaIN.txt conține pe prima linie numărul n, iar pe a doua linie 4 numere naturale separate prin spații, care semnifică coordonatele celulei în care se află Jaina și coordonatele celulei în care se află Antonidas. ( 2 perechi linie-coloană )

A treia linie conține numărul m de surse de energie.

Pe următoarele m linii se află câte două numere naturale x y, reprezentând coordonatele fiecărei surse.

Date de ieșire

Fișierul de ieșire jainaOUT.txt va conține pe prima linie numărul nrp, reprezentând numărul minim de pași pe care Jaina trebuie să-i efectueze pentru a ajunge la Antonidas. În cazul în care restricțiile nu sunt îndeplinite, se va afișa mesajul "Datele nu corespund restrictiilor impuse".

Restricții și precizări

  • 1 ≤ n ≤ 100
  • 1 ≤ m ≤ 10
  • Orice celulă are dimensiunea 1x1
  • În cazul în care Jaina se află la intersecția a două raze de surse diferite, aceasta se va teleporta la sursa de linie minimă.
  • Nu există două surse care să se afle pe aceeași linie sau pe aceeași coloană.
  • Se garantează că există soluție pentru toate testele.
  • Antonidas promite că o să fiți răsplătiți cu o minge de foc dacă găsiți răspunsul corect la această problemă.
  • Deoarece Jaina este disperată, limitele de memorie sunt foarte mari, însă pe viitor nu este garantat acest lucru!

Exemplul 1:

jainaIN.txt

4
2 1 4 4 
1
3 3

jainaOUT.txt

2

Explicație

Numărul de pași necesari în acest caz este 2.

Exemplul 2:

jainaIN.txt

4
2 1 4 4 
1
3 3

jainaOUT.txt

Datele nu corespund restrictiilor impuse

Rezolvare

from collections import deque

class Celula:
    def __init__(self):
        self.val = 0
        self.laser = 0
        self.xs = 0
        self.ys = 0

nmax = 100
dl = [-1, -1, -1, 0, 1, 1, 1, 0]
dc = [-1, 0, 1, 1, 1, 0, -1, -1]

def inside(x, y, n):
    return 1 <= x <= n and 1 <= y <= n

def nord_sud(x, y, a, n):
    for i in range(1, n + 1):
        if a[i][y].laser == 0 and i != x:
            a[i][y].laser = 1
            a[i][y].xs = x
            a[i][y].ys = y
        elif i != x:
            if x < a[i][y].xs:
                a[i][y].xs = x
                a[i][y].ys = y

def est_vest(x, y, a, n):
    for j in range(1, n + 1):
        if a[x][j].laser == 0 and j != y:
            a[x][j].laser = 1
            a[x][j].xs = x
            a[x][j].ys = y
        elif j != y:
            if x < a[x][j].xs:
                a[x][j].xs = x
                a[x][j].ys = y

def solve(n, xi, yi, xf, yf, m, a):
    q = deque([(xi, yi)])
    a[xi][yi].val = 1

    while q:
        f1, f2 = q.popleft()

        for k in range(8):
            iv = f1 + dl[k]
            jv = f2 + dc[k]

            if inside(iv, jv, n) and (not a[iv][jv].val or a[iv][jv].val > a[f1][f2].val + 1):
                if a[iv][jv].laser == 0:
                    a[iv][jv].val = a[f1][f2].val + 1
                    q.append((iv, jv))
                else:
                    lin = a[iv][jv].xs
                    col = a[iv][jv].ys
                    a[iv][jv].val = a[f1][f2].val + 1

                    if a[lin][col].val > a[iv][jv].val or not a[lin][col].val:
                        a[lin][col].val = a[iv][jv].val
                        q.append((lin, col))
                        q.append((iv, jv))

    return a[xf][yf].val - 1

def verificare_restrictii(n, m):
    if not (1 <= n <= 100 and 1 <= m <= 10):
        with open("jainaOUT.txt", "w") as f:
            f.write("Datele nu corespund restrictiilor impuse")
        return False
    return True

def citire():
    with open("jainaIN.txt", "r") as f:
        n = int(f.readline().strip())
        xi, yi, xf, yf = map(int, f.readline().split())
        m = int(f.readline().strip())
        if not verificare_restrictii(n, m):
            exit()  # Ieșire din program dacă restricțiile nu sunt respectate
        a = [[Celula() for _ in range(nmax + 1)] for _ in range(nmax + 1)]
        for _ in range(m):
            x, y = map(int, f.readline().split())
            nord_sud(x, y, a, n)
            est_vest(x, y, a, n)
    return n, xi, yi, xf, yf, a

def scriere(result):
    with open("jainaOUT.txt", "w") as f:
        f.write(str(result))

def main():
    n, xi, yi, xf, yf, a = citire()
    result = solve(n, xi, yi, xf, yf, n, a)
    scriere(result)

if __name__ == "__main__":
    main()