3696 - taxa: Difference between revisions

From Bitnami MediaWiki
Pagină nouă: == Enunt == Miruna se pregăteşte de vacanţa de vară. Ea a hotărât deja că împreună cu un grup de colegi să facă o excursie în regatul INFO unde moneda locală se numeşte BOSS. A studiat deja harta acestei zone şi a aflat multe lucruri interesante. Ea ştie că regatul se află pe o insula cu suprafaţa uscatului sub forma dreptunghiulară ce poate fi reprezentată ca o matrice cu N linii şi M coloane în care fiecare element este un cod pentru un tip de obiect...
 
No edit summary
 
Line 1: Line 1:
== Enunt ==
== Enunt ==


Miruna se pregăteşte de vacanţa de vară. Ea a hotărât deja că împreună cu un grup de colegi să facă o excursie în regatul INFO unde moneda locală se numeşte BOSS. A studiat deja harta acestei zone şi a aflat multe lucruri interesante. Ea ştie că regatul se află pe o insula cu suprafaţa uscatului sub forma dreptunghiulară ce poate fi reprezentată ca o matrice cu N linii şi M coloane în care fiecare element este un cod pentru un tip de obiectiv turistic ce poate fi vizitat. Deoarece sosirea şi plecarea de pe insulă se face cu avionul, ea cunoaşte poziția (l0,c0) unde va fi debarcată şi poziţia (lf,cf) unde va fi plecarea de pe insulă. Ea se poate deplasa pentru vizitarea obiectivelor turistice doar în celule vecine pe cele opt direcţii (N, S, E, V, NE, NV, SE, SV), iar dacă nouă poziţie are alt cod decât cel din care venise la pasul precedent, atunci trebuie să plătească o taxa de vizitare egală cu produsul codurilor celor doua zone (exprimată tot în moneda locală, BOSS!!!). Miruna ar dori să afle care ar fi suma minimă necesară pentru a se deplasa până la locul de plecare de pe insulă.
Miruna se pregăteşte de vacanţa de vară. Ea a hotărât deja că împreună cu un grup de colegi să facă o excursie în regatul INFO unde moneda locală se numeşte BOSS. A studiat deja harta acestei zone şi a aflat multe lucruri interesante. Ea ştie că regatul se află pe o insula cu suprafaţa uscatului sub forma dreptunghiulară ce poate fi reprezentată ca o matrice cu <code>N</code> linii şi <code>M</code> coloane în care fiecare element este un cod pentru un tip de obiectiv turistic ce poate fi vizitat. Deoarece sosirea şi plecarea de pe insulă se face cu avionul, ea cunoaşte poziția <code>(l0,c0)</code> unde va fi debarcată şi poziţia <code>(lf,cf)</code> unde va fi plecarea de pe insulă. Ea se poate deplasa pentru vizitarea obiectivelor turistice doar în celule vecine pe cele opt direcţii (<code>N</code>, <code>S</code>, <code>E</code>, <code>V</code>, <code>NE</code>, <code>NV</code>, <code>SE</code>, <code>SV</code>), iar dacă nouă poziţie are alt cod decât cel din care venise la pasul precedent, atunci trebuie să plătească o taxa de vizitare egală cu produsul codurilor celor doua zone (exprimată tot în moneda locală, BOSS!!!). Miruna ar dori să afle care ar fi suma minimă necesară pentru a se deplasa până la locul de plecare de pe insulă.
 
== Cerinta ==


= Cerința =
Dându-se configuraţia regatului şi poziţiile de plecare şi sosire, să se determine suma minimă necesară deplasării.
Dându-se configuraţia regatului şi poziţiile de plecare şi sosire, să se determine suma minimă necesară deplasării.


== Date de intrare ==
= Date de intrare =
 
Pe prima linie a fişierului <code>taxaIN.txt</code> se află valorile naturale <code>N</code>, <code>M</code>, <code>l0</code>, <code>c0</code>, <code>lf</code>, <code>cf</code>. Pe următoarele <code>N</code> linii se află câte <code>M</code> elemente, codurile fiecărei zone, numere naturale separate prin câte un spaţiu.
Pe prima linie a fişierului taxa.in se află valorile naturale N, M, l0, c0, lf, cf. Pe următoarele N linii se află câte M elemente, codurile fiecărei zone, numere naturale separate prin câte un spaţiu.
 
== Date de ieșire ==
 
Fișierul de ieșire taxa.out va conține un număr natural B, reprezentând suma minimă necesară deplasării.
 
== Restrictii si precizari ==
 
*0 < N, M < 1001
*Obiectivele au coduri numere naturale nenule mai mici sau egale cu 5, iar poziţia inițială şi finală sunt distincte
*Pentru 30% din teste vom avea N, M ≤ 100
*Pentru 20% din teste matricea conţine numai două valori.
 
== Exemplul 1 ==
 
;taxain.txt
 
:5 5 1 1 4 5
 
:1 1 2 2 2
 
:1 2 3 3 3
 
:1 1 3 3 3
 
:2 2 2 2 2
 
:1 1 1 2 1
 
;taxaout.txt


:Datele introduse corespund restrictiilor impuse.
= Date de ieșire =
Fișierul de ieșire <code>taxaOUT.txt</code> va conține un număr natural <code>B</code>, reprezentând suma minimă necesară deplasării. În cazul în care restricțiile nu sunt îndeplinite, se va afișa mesajul "Datele nu corespund restrictiilor impuse".


:2
= Restricții și precizări =


== Exemplul 2 ==
* <code>0 < N, M < 1001</code>
* Obiectivele au coduri numere naturale nenule mai mici sau egale cu <code>5</code>, iar poziţia inițială şi finală sunt distincte
* Pentru 30% din teste vom avea <code>N, M ≤ 100</code>
* Pentru 20% din teste matricea conţine numai două valori.


;taxain.txt
= Exemplul 1: =
<code>taxaIN.txt</code>
5 5 1 1 4 5
1 1 2 2 2
1 2 3 3 3
1 1 3 3 3
2 2 2 2 2
1 1 1 2 1
<code>taxaOUT.txt</code>
2


:86 453 53 4
== Explicație ==
Suma minimă necesară deplasării din <code>(1,1)</code> în <code>(4,5)</code> este de <code>2</code> BOSSi.


:-3 32 0 -3
= Exemplul 2: =
 
<code>taxaIN.txt</code>
:22 9 323 43
1002 5 1 1 4 5
 
1 1 2 2 2
:12 94 732 43
1 2 3 3 3
 
1 1 3 3 3
:-2 -3 -34 -4
  2 2 2 2 2
 
1 1 1 2 1
:12 32 43 65
<code>taxaOUT.txt</code>
 
Datele nu corespund restrictiilor impuse
;taxaout.txt
 
:Datele de intrare nu corespund restrictiilor impuse.
 
== Rezolvare ==


=== Rezolvare ===
<syntaxhighlight lang="python3" line="1">
<syntaxhighlight lang="python3" line="1">
from queue import Queue


import heapq
dl = [-1, -1, -1, 0, 1, 1, 1, 0]
 
dc = [-1, 0, 1, 1, 1, 0, -1, -1]
def suma_minima_deplasare(regat, sosire, plecare):
    N = len(regat)
    M = len(regat[0])
 
    # Pasul 1: Construirea grafului
    graf = construieste_graf(regat, N, M)
 
    # Pasul 2: Calculul drumului minim
    suma_minima = dijkstra(graf, sosire, plecare)
 
    return suma_minima
 
def construieste_graf(regat, N, M):
    graf = {}
 
    for i in range(N):
        for j in range(M):
            cod_curent = regat[i][j]
            nod_curent = (i, j)
 
            if nod_curent not in graf:
                graf[nod_curent] = {}
 
            vecini = get_vecini(N, M, i, j)
            for vecin in vecini:
                i_vecin, j_vecin = vecin
                cod_vecin = regat[i_vecin][j_vecin]
                cost = cod_curent * cod_vecin
                nod_vecin = (i_vecin, j_vecin)
 
                if nod_vecin not in graf[nod_curent]:
                    graf[nod_curent][nod_vecin] = cost


     return graf
def inside(x, y, n, m):
     return x >= 0 and x < n and y >= 0 and y < m


def get_vecini(N, M, i, j):
def fill(x, y, x0, y0, c):
     vecini = []
     if inside(x, y, n, m) and cost[x][y] == -1:
        if a[x][y] == a[x0][y0]:
            cost[x][y] = c
            for p in range(8):
                fill(x + dl[p], y + dc[p], x0, y0, c)
        else:
            q[c + a[x][y] * a[x0][y0]].put((x, y))


     for di in [-1, 0, 1]:
def pseudo_lee():
        for dj in [-1, 0, 1]:
     q[0].put((l0, c0))
            if di == 0 and dj == 0:
                continue


             i_vecin, j_vecin = i + di, j + dj
    for i in range(CMAX):
            if 0 <= i_vecin < N and 0 <= j_vecin < M:
        while not q[i].empty():
                vecini.append((i_vecin, j_vecin))
             iv, jv = q[i].get()


    return vecini
            if cost[iv][jv] == -1:
                fill(iv, jv, iv, jv, i)


def dijkstra(graf, sosire, plecare):
            if cost[lf][cf] != -1:
    distante = {nod: float('inf') for nod in graf}
                return cost[lf][cf]
    distante[sosire] = 0


     heap = [(0, sosire)]
def validate_restrictions(n, m, l0, c0, lf, cf):
     if not (0 < n <= 1000 and 0 < m <= 1000):
        return False
    if not (0 <= l0 - 1 < n and 0 <= c0 - 1 < m and 0 <= lf - 1 < n and 0 <= cf - 1 < m):
        return False
    if (l0, c0) == (lf, cf):
        return False
    return True


     while heap:
with open("taxaIN.txt", "r") as in_file:
         cost_curent, nod_curent = heapq.heappop(heap)
    n, m, l0, c0, lf, cf = map(int, in_file.readline().split())
    # Verificăm dacă datele de intrare respectă restricțiile
     if not validate_restrictions(n, m, l0, c0, lf, cf):
         with open("taxaOUT.txt", "w") as out_file:
            out_file.write("Datele nu corespund restrictiilor impuse")
        exit() # Oprim execuția dacă datele nu respectă restricțiile


        if cost_curent > distante[nod_curent]:
    # Deoarece datele sunt indexate de la 1, le ajustăm indexul
            continue
    l0 -= 1
    c0 -= 1
    lf -= 1
    cf -= 1


        for vecin, cost in graf[nod_curent].items():
    a = []
            cost_total = cost_curent + cost
    cost = []
    for _ in range(n):
        row = list(map(int, in_file.readline().split()))
        a.append(row)
        cost.append([-1] * m)


            if cost_total < distante[vecin]:
CMAX = 4 * 10 ** 4 + 10
                distante[vecin] = cost_total
q = [Queue() for _ in range(CMAX + 5)]
                heapq.heappush(heap, (cost_total, vecin))


    return distante[plecare]
result = pseudo_lee()


rezultat = suma_minima_deplasare(regat, sosire, plecare)
with open("taxaOUT.txt", "w") as out_file:
print(rezultat)
    out_file.write(str(result))


</syntaxhighlight>
</syntaxhighlight>

Latest revision as of 20:40, 22 March 2024

Enunt[edit | edit source]

Miruna se pregăteşte de vacanţa de vară. Ea a hotărât deja că împreună cu un grup de colegi să facă o excursie în regatul INFO unde moneda locală se numeşte BOSS. A studiat deja harta acestei zone şi a aflat multe lucruri interesante. Ea ştie că regatul se află pe o insula cu suprafaţa uscatului sub forma dreptunghiulară ce poate fi reprezentată ca o matrice cu N linii şi M coloane în care fiecare element este un cod pentru un tip de obiectiv turistic ce poate fi vizitat. Deoarece sosirea şi plecarea de pe insulă se face cu avionul, ea cunoaşte poziția (l0,c0) unde va fi debarcată şi poziţia (lf,cf) unde va fi plecarea de pe insulă. Ea se poate deplasa pentru vizitarea obiectivelor turistice doar în celule vecine pe cele opt direcţii (N, S, E, V, NE, NV, SE, SV), iar dacă nouă poziţie are alt cod decât cel din care venise la pasul precedent, atunci trebuie să plătească o taxa de vizitare egală cu produsul codurilor celor doua zone (exprimată tot în moneda locală, BOSS!!!). Miruna ar dori să afle care ar fi suma minimă necesară pentru a se deplasa până la locul de plecare de pe insulă.

Cerința[edit | edit source]

Dându-se configuraţia regatului şi poziţiile de plecare şi sosire, să se determine suma minimă necesară deplasării.

Date de intrare[edit | edit source]

Pe prima linie a fişierului taxaIN.txt se află valorile naturale N, M, l0, c0, lf, cf. Pe următoarele N linii se află câte M elemente, codurile fiecărei zone, numere naturale separate prin câte un spaţiu.

Date de ieșire[edit | edit source]

Fișierul de ieșire taxaOUT.txt va conține un număr natural B, reprezentând suma minimă necesară deplasării. În cazul în care restricțiile nu sunt îndeplinite, se va afișa mesajul "Datele nu corespund restrictiilor impuse".

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

  • 0 < N, M < 1001
  • Obiectivele au coduri numere naturale nenule mai mici sau egale cu 5, iar poziţia inițială şi finală sunt distincte
  • Pentru 30% din teste vom avea N, M ≤ 100
  • Pentru 20% din teste matricea conţine numai două valori.

Exemplul 1:[edit | edit source]

taxaIN.txt

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

taxaOUT.txt

2

Explicație[edit | edit source]

Suma minimă necesară deplasării din (1,1) în (4,5) este de 2 BOSSi.

Exemplul 2:[edit | edit source]

taxaIN.txt

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

taxaOUT.txt

Datele nu corespund restrictiilor impuse

Rezolvare[edit | edit source]

<syntaxhighlight lang="python3" line="1"> from queue import Queue

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

def inside(x, y, n, m):

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

def fill(x, y, x0, y0, c):

   if inside(x, y, n, m) and cost[x][y] == -1:
       if a[x][y] == a[x0][y0]:
           cost[x][y] = c
           for p in range(8):
               fill(x + dl[p], y + dc[p], x0, y0, c)
       else:
           q[c + a[x][y] * a[x0][y0]].put((x, y))

def pseudo_lee():

   q[0].put((l0, c0))
   for i in range(CMAX):
       while not q[i].empty():
           iv, jv = q[i].get()
           if cost[iv][jv] == -1:
               fill(iv, jv, iv, jv, i)
           if cost[lf][cf] != -1:
               return cost[lf][cf]

def validate_restrictions(n, m, l0, c0, lf, cf):

   if not (0 < n <= 1000 and 0 < m <= 1000):
       return False
   if not (0 <= l0 - 1 < n and 0 <= c0 - 1 < m and 0 <= lf - 1 < n and 0 <= cf - 1 < m):
       return False
   if (l0, c0) == (lf, cf):
       return False
   return True

with open("taxaIN.txt", "r") as in_file:

   n, m, l0, c0, lf, cf = map(int, in_file.readline().split())
   # Verificăm dacă datele de intrare respectă restricțiile
   if not validate_restrictions(n, m, l0, c0, lf, cf):
       with open("taxaOUT.txt", "w") as out_file:
           out_file.write("Datele nu corespund restrictiilor impuse")
       exit()  # Oprim execuția dacă datele nu respectă restricțiile
   # Deoarece datele sunt indexate de la 1, le ajustăm indexul
   l0 -= 1
   c0 -= 1
   lf -= 1
   cf -= 1
   a = []
   cost = []
   for _ in range(n):
       row = list(map(int, in_file.readline().split()))
       a.append(row)
       cost.append([-1] * m)

CMAX = 4 * 10 ** 4 + 10 q = [Queue() for _ in range(CMAX + 5)]

result = pseudo_lee()

with open("taxaOUT.txt", "w") as out_file:

   out_file.write(str(result))

</syntaxhighlight>