1117 - Volum: Diferență între versiuni

De la Universitas MediaWiki
(Pagină nouă: K.L. 2.0 și-a dorit o piscină pe un grid A cu N linii și M coloane. Cum K.L. 2.0 nu a fost foarte inspirat, el a uitat să își niveleze terenul înainte de a construi piscina, astfel încât fiecare celulă de coordonate (i, j) a gridului are o înalțime Ai,j (1 ≤ i ≤ N și 1 ≤ j ≤ M). La un moment dat începe o ploaie puternică, care umple piscina cu apă. După terminarea ploii, K.L. 2.0 se întreabă câtă apă are în piscină. Dintr-o celulă apa se vars...)
 
Fără descriere a modificării
 
Linia 1: Linia 1:
K.L. 2.0 și-a dorit o piscină pe un grid A cu N linii și M coloane. Cum K.L. 2.0 nu a fost foarte inspirat, el a uitat să își niveleze terenul înainte de a construi piscina, astfel încât fiecare celulă de coordonate (i, j) a gridului are o înalțime Ai,j (1 ≤ i ≤ N și 1 ≤ j ≤ M). La un moment dat începe o ploaie puternică, care umple piscina cu apă. După terminarea ploii, K.L. 2.0 se întreabă câtă apă are în piscină.
K.L. 2.0 și-a dorit o piscină pe un grid <code>A</code> cu <code>N</code> linii și <code>M</code> coloane. Cum K.L. 2.0 nu a fost foarte inspirat, el a uitat să își niveleze terenul înainte de a construi piscina, astfel încât fiecare celulă de coordonate <code>(i, j)</code> a gridului are o înalțime <code>Ai,j</code> (<code>1 ≤ i ≤ N</code> și <code>1 ≤ j ≤ M</code>). La un moment dat începe o ploaie puternică, care umple piscina cu apă. După terminarea ploii, K.L. 2.0 se întreabă câtă apă are în piscină.


Dintr-o celulă apa se varsă în celulele vecine cu care are o latură comună şi care au înălţimea strict mai mică decât celula curentă. Apa de pe marginea piscinei se scurge în exterior.
Dintr-o celulă apa se varsă în celulele vecine cu care are o latură comună şi care au înălţimea strict mai mică decât celula curentă. Apa de pe marginea piscinei se scurge în exterior.
== Cerința ==
 
Pentru N, M și gridul A date, să se determine volumul de apă care a rămas în piscină.
= Cerință =
== Date de intrare ==
Pentru <code>N</code>, <code>M</code> și gridul <code>A</code> date, să se determine volumul de apă care a rămas în piscină.
Fișierul de intrare volumin.txt conține pe prima linie două numere naturale N și M, reprezentând dimensiunile grid-ului, iar pe fiecare dintre următoarele N linii se află câte M numere, reprezentând înălțimile terenului, separate prin câte un spațiu.
 
== Date de ieșire ==  
= Date de intrare =
Fișierul de ieșire volumout.txt va conține un singur număr, reprezentând volumul de apă care a rămas în piscină.
Fișierul de intrare <code>volumIN.txt</code> conține pe prima linie două numere naturale <code>N</code> și <code>M</code>, reprezentând dimensiunile grid-ului, iar pe fiecare dintre următoarele <code>N</code> linii se află câte <code>M</code> numere, reprezentând înălțimile terenului, separate prin câte un spațiu.
== Restricții și precizări ==
 
*'''3 ≤ N, M ≤ 752'''
= Date de ieșire =
*'''0 ≤ Ai,j ≤ 109 + 2'''
Fișierul de ieșire <code>volumOUT.txt</code> va conține un singur număr, reprezentând volumul de apă care a rămas în piscină. În cazul în care restricțiile nu sunt îndeplinite, se va afișa mesajul "Datele nu corespund restrictiilor impuse".
*Pentru 30% din punctaj, '''3 ≤ N, M ≤ 82'''.
 
*Pentru 40% din punctaj, '''0 ≤ Ai,j ≤ 103 + 2'''.
= Restricții și precizări =
*Volumul apei este suma unităţilor de apă care rămâne în celulele piscinei.
 
== Exemplul 1 ==
* <code>3 ≤ N, M ≤ 752</code>
; volumin.txt
* <code>0 ≤ Ai,j ≤ 109 + 2</code>
: 3 3
* Pentru 30% din punctaj, <code>3 ≤ N, M ≤ 82</code>.
: 2 2 2
* Pentru 40% din punctaj, <code>0 ≤ Ai,j ≤ 103 + 2</code>.
: 2 0 2
* Volumul apei este suma unităţilor de apă care rămâne în celulele piscinei.
: 2 2 2
 
; volum.out
= Exemplul 1: =
: 2
<code>volum.in</code>
<br>
3 3
== Explicatie ==  
2 2 2
După ploaie rămân două unități de apă în celula cu înălțimea 0. Nu pot rămâne 3 unități, deoarece o unitate s-ar scurge prin una din cele 4 celule vecine în exteriorul piscinei.
2 0 2
== Exemplul 2 ==
2 2 2
; volumin.txt
<code>volum.out</code>
: 3 3
2
: 3 3 3
 
: 3 0 2
= Explicație =
: 3 3 3
După ploaie rămân două unități de apă în celula cu înălțimea <code>0</code>. Nu pot rămâne <code>3</code> unități, deoarece o unitate s-ar scurge prin una din cele 4 celule vecine în exteriorul piscinei.
; volumout.txt
 
: 2
= Exemplul 2: =
<br>
<code>volumIN.txt</code>
== Explicatie ==  
3 3
După ploaie rămân două unități de apă în celula cu înălțimea 0. Nu pot rămâne 3 unități, deoarece o unitate s-ar scurge prin celula vecină cu valoarea 2 în exteriorul piscinei.
3 3 3
3 0 2
3 3 3
<code>volumOUT.txt</code>
2
 
= Explicație =
După ploaie rămân două unități de apă în celula cu înălțimea <code>0</code>. Nu pot rămâne <code>3</code> unități, deoarece o unitate s-ar scurge prin celula vecină cu valoarea <code>2</code> în exteriorul piscinei.
 
== Exemplul 3: ==
<code>volumIN.txt</code>
1 3
3 3 3
3 0 2
3 3 3
<code>volumOUT.txt</code>
Datele nu corespund restrictiilor impuse
 
= Exemplul 4: =
<code>volumIN.txt</code>
5 5
2 2 3 3 3
2 2 3 1 3
2 3 1 3 3
2 2 3 2 2
2 2 2 2 2
<code>volumOUT.txt</code>
4
 
= Explicație =
După ploaie rămân câte două unități de apă în celulele cu înălțimea <code>1</code>. Nu pot rămâne câte <code>3</code> unități. De exemplu, din celula <code>(2,4)</code> apa se poate scurge în celula <code>(2,5)</code> şi apoi în exterior, respectiv din celula <code>(3,3)</code> în şirul de celule <code>(4,3) - (5,3)</code> şi apoi în exterior.
 
== Rezolvare ==  
== Rezolvare ==  
<syntaxhighlight lang="python" line>
<syntaxhighlight lang="python" line="1">
#1117 - Volum
import heapq
def volum_apa(N, M, A):
    if not (3 <= N <= 752 and 3 <= M <= 752):
        return "Fals"


    for i in range(N):
maxn = 755
        for j in range(M):
n, m = 0, 0
            if not (0 <= A[i][j] <= 109 + 2):
v = [[0] * maxn for _ in range(maxn)]
                return "Fals"
f = [[0] * maxn for _ in range(maxn)]
sol = 0
hp = []
d1 = [0, 0, -1, 1]
d2 = [1, -1, 0, 0]


    directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
def add_element(x, y, h):
    global sol
    if x <= 0 or y <= 0 or x > n or y > m:
        return
    if f[x][y] == 1:
        return


     def bfs(i, j):
     if h < v[x][y]:
         queue = [(i, j)]
         h = v[x][y]
        visited[i][j] = True
    sol += h - v[x][y]


        while queue:
    heapq.heappush(hp, (h, x, y))
            x, y = queue.pop(0)
    f[x][y] = 1


            for dx, dy in directions:
def check_constraints():
                nx, ny = x + dx, y + dy
    if not (3 <= n <= 752 and 3 <= m <= 752):
        return False
    for i in range(1, n + 1):
        for j in range(1, m + 1):
            if not (0 <= v[i][j] <= 10**9 + 2):
                return False
    return True


                if 0 <= nx < N and 0 <= ny < M and not visited[nx][ny]:
def main():
                    if A[nx][ny] < A[i][j]:
    global n, m, sol
                        water_volume[0] += A[i][j] - A[nx][ny]
                        queue.append((nx, ny))
                        visited[nx][ny] = True


     water_volume = [0]
     with open("volumIN.txt", "r") as fin:
    visited = [[False] * M for _ in range(N)]
        n, m = map(int, fin.readline().split())
        for i in range(1, n + 1):
            v[i][1:m + 1] = map(int, fin.readline().split())


     for i in range(N):
     if not check_constraints():
         bfs(i, 0)
         with open("volumOUT.txt", "w") as fout:
        bfs(i, M - 1)
            fout.write("Datele nu corespund restrictiilor impuse\n")
        return


     for j in range(M):
    for i in range(1, n + 1):
         bfs(0, j)
        add_element(i, 1, v[i][1])
         bfs(N - 1, j)
        add_element(i, m, v[i][m])
     for j in range(1, m + 1):
         add_element(1, j, v[1][j])
         add_element(n, j, v[n][j])


     return water_volume[0]
     while len(hp) > 0:
        hc, xc, yc = heapq.heappop(hp)


# Citirea datelor de intrare din fișierul "volumin.txt"
        for i in range(4):
with open("volumin.txt", "r") as file:
            add_element(xc + d1[i], yc + d2[i], hc)
    N, M = map(int, file.readline().split())
    A = [list(map(int, file.readline().split())) for _ in range(N)]


# Calcularea volumului de apă rămas în piscină
    with open("volumOUT.txt", "w") as fout:
result = volum_apa(N, M, A)
        fout.write(f"{sol}\n")


# Scrierea rezultatului în fișierul "volumout.txt"
if __name__ == "__main__":
with open("volumout.txt", "w") as file:
     main()
     file.write(str(result))


</syntaxhighlight>
</syntaxhighlight>

Versiunea curentă din 18 mai 2024 07:39

K.L. 2.0 și-a dorit o piscină pe un grid A cu N linii și M coloane. Cum K.L. 2.0 nu a fost foarte inspirat, el a uitat să își niveleze terenul înainte de a construi piscina, astfel încât fiecare celulă de coordonate (i, j) a gridului are o înalțime Ai,j (1 ≤ i ≤ N și 1 ≤ j ≤ M). La un moment dat începe o ploaie puternică, care umple piscina cu apă. După terminarea ploii, K.L. 2.0 se întreabă câtă apă are în piscină.

Dintr-o celulă apa se varsă în celulele vecine cu care are o latură comună şi care au înălţimea strict mai mică decât celula curentă. Apa de pe marginea piscinei se scurge în exterior.

Cerință

Pentru N, M și gridul A date, să se determine volumul de apă care a rămas în piscină.

Date de intrare

Fișierul de intrare volumIN.txt conține pe prima linie două numere naturale N și M, reprezentând dimensiunile grid-ului, iar pe fiecare dintre următoarele N linii se află câte M numere, reprezentând înălțimile terenului, separate prin câte un spațiu.

Date de ieșire

Fișierul de ieșire volumOUT.txt va conține un singur număr, reprezentând volumul de apă care a rămas în piscină. În cazul în care restricțiile nu sunt îndeplinite, se va afișa mesajul "Datele nu corespund restrictiilor impuse".

Restricții și precizări

  • 3 ≤ N, M ≤ 752
  • 0 ≤ Ai,j ≤ 109 + 2
  • Pentru 30% din punctaj, 3 ≤ N, M ≤ 82.
  • Pentru 40% din punctaj, 0 ≤ Ai,j ≤ 103 + 2.
  • Volumul apei este suma unităţilor de apă care rămâne în celulele piscinei.

Exemplul 1:

volum.in

3 3
2 2 2
2 0 2
2 2 2

volum.out

2

Explicație

După ploaie rămân două unități de apă în celula cu înălțimea 0. Nu pot rămâne 3 unități, deoarece o unitate s-ar scurge prin una din cele 4 celule vecine în exteriorul piscinei.

Exemplul 2:

volumIN.txt

3 3
3 3 3
3 0 2
3 3 3

volumOUT.txt

2

Explicație

După ploaie rămân două unități de apă în celula cu înălțimea 0. Nu pot rămâne 3 unități, deoarece o unitate s-ar scurge prin celula vecină cu valoarea 2 în exteriorul piscinei.

Exemplul 3:

volumIN.txt

1 3
3 3 3
3 0 2
3 3 3

volumOUT.txt

Datele nu corespund restrictiilor impuse

Exemplul 4:

volumIN.txt

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

volumOUT.txt

4

Explicație

După ploaie rămân câte două unități de apă în celulele cu înălțimea 1. Nu pot rămâne câte 3 unități. De exemplu, din celula (2,4) apa se poate scurge în celula (2,5) şi apoi în exterior, respectiv din celula (3,3) în şirul de celule (4,3) - (5,3) şi apoi în exterior.

Rezolvare

import heapq

maxn = 755
n, m = 0, 0
v = [[0] * maxn for _ in range(maxn)]
f = [[0] * maxn for _ in range(maxn)]
sol = 0
hp = []
d1 = [0, 0, -1, 1]
d2 = [1, -1, 0, 0]

def add_element(x, y, h):
    global sol
    if x <= 0 or y <= 0 or x > n or y > m:
        return
    if f[x][y] == 1:
        return

    if h < v[x][y]:
        h = v[x][y]
    sol += h - v[x][y]

    heapq.heappush(hp, (h, x, y))
    f[x][y] = 1

def check_constraints():
    if not (3 <= n <= 752 and 3 <= m <= 752):
        return False
    for i in range(1, n + 1):
        for j in range(1, m + 1):
            if not (0 <= v[i][j] <= 10**9 + 2):
                return False
    return True

def main():
    global n, m, sol

    with open("volumIN.txt", "r") as fin:
        n, m = map(int, fin.readline().split())
        for i in range(1, n + 1):
            v[i][1:m + 1] = map(int, fin.readline().split())

    if not check_constraints():
        with open("volumOUT.txt", "w") as fout:
            fout.write("Datele nu corespund restrictiilor impuse\n")
        return

    for i in range(1, n + 1):
        add_element(i, 1, v[i][1])
        add_element(i, m, v[i][m])
    for j in range(1, m + 1):
        add_element(1, j, v[1][j])
        add_element(n, j, v[n][j])

    while len(hp) > 0:
        hc, xc, yc = heapq.heappop(hp)

        for i in range(4):
            add_element(xc + d1[i], yc + d2[i], hc)

    with open("volumOUT.txt", "w") as fout:
        fout.write(f"{sol}\n")

if __name__ == "__main__":
    main()