4183 - Bac Eroziune

De la Universitas MediaWiki

Sursă: [1]

Enunt

Pentru prevenirea eroziunii la Marea Neagră, autoritățile au hotărât înnisiparea unei plaje. Plaja a fost împărțită în parcele de formă pătrată cu latura de 1 metru, dispuse ca elementele unui tablou bidimensional, reținându-se nivelul fiecărei parcele, măsurat în metri, de la nivelul mării. Înnisiparea se realizează doar pe acele parcele care au nivelul strict mai mic decât al celei mai joase dintre parcelele vecine cu ea, adăugând nisip, astfel încât cele două să aibă același nivel. Două parcele sunt vecine dacă au o latură comună.

Cerință

Scrieți un program C/C++ care citește de la tastatură două numere naturale L și C, apoi elementele unui tablou bidimensional cu L linii şi C coloane reprezentând nivelurile parcelelor, în ordinea dispunerii acestora pe plajă și determină cantitatea totală de nisip adăugată, măsurată în metri cubi.

Date de intrare

Programul citește de la tastatură două numere naturale L și C, apoi elementele unui tablou bidimensional cu L linii şi C coloane reprezentând nivelurile parcelelor.

Date de ieșire

Dacă datele sunt introduse corect, pe ecran se va afișa: "Datele sunt corecte."'. Programul va afișa pe ecran numărul S, reprezentând cantitatea totală de nisip adăugată, măsurată în metri cubi. În caz contrar, se va afișa pe ecran: "Datele nu sunt comform restricțiilor impuse.".

Restricții și precizări

  • 1 ≤ L, C ≤ 100
  • Elementele tabloului bidimensional sunt numere naturale cuprinse între 1 și 10

Exemple

Exemplu 1

Date de intrare
5 4
5 3 4 6
7 5 9 3
6 8 3 9
4 5 2 3
3 1 4 4
Date de ieșire
7

Explicatie

Se vor înnisipa parcelele de la pozițiile (1,2), (2,4), (4,3), (5,2) pentru a fi aduse la nivelul parcelelor vecine corespunzătoare și se va afișa valoarea 7 (1 + 3 + 1 + 2).

Rezolvare

def citire_matrice():
    try:
        n = int(input("Introduceti numarul de linii: "))
        m = int(input("Introduceti numarul de coloane: "))
        if 1 <= n <= 100 and 1 <= m <= 100:
            print("Datele sunt corecte.")
        else:
            print("Datele nu sunt conform restrictiilor impuse.")
            exit()
    except ValueError:
        print("Trebuie introduse doar numere intregi.")
        exit()

    matrice = []
    for linie in range(n):
        matrice.append([])
        for coloana in range(m):
            for i in range(3):
                try:
                    valoare = int(input(f"Introduceti un numar pentru linia {linie+1}, coloana {coloana+1}: "))
                    if valoare <= 1000000:
                        print("Datele sunt corecte.")
                        matrice[linie].append(valoare)
                        break
                    else:
                        print("Datele nu sunt conform restrictiilor impuse.")
                except ValueError:
                    print("Trebuie introduse doar numere intregi.")
            else:
                print("Prea multe incercari esuate.")
                exit()

    return n, m, matrice

def bac_eroziune(valori, n):
    nisip_total = 0
    for i in range(n):
        for j in range(len(valori[i])):
            vecini = []
            nivel = valori[i][j]
            if i > 0:
                vecini.append(valori[i-1][j])
            if j > 0:
                vecini.append(valori[i][j-1])
            if i < n-1:
                vecini.append(valori[i+1][j])
            if j < len(valori[i])-1:
                vecini.append(valori[i][j+1])
            vecini.sort()
            if nivel < vecini[0]:
                nisip = vecini[0] - nivel
                valori[i][j] += nisip
                nisip_total += nisip
    return nisip_total

if _name_ == '_main_':
    n, m, matrice = citire_matrice()
    print("Cantitatea totala de nisip adaugata: ", bac_eroziune(matrice, n))

Explicatie

Acest cod este scris in limbajul Python si contine doua functii: citire_matrice() si bac_eroziune(). De asemenea, se verifica si se afiseaza rezultatul.
Functia citire_matrice() solicita de la utilizator numarul de linii si coloane ale matricei, apoi verifica daca valorile introduse se incadreaza in intervalul permis (1-100). Daca valorile sunt valide, se solicita utilizatorului sa introduca valorile matricei. De asemenea, se verifica daca valorile introduse se incadreaza in intervalul permis (<= 1000000). Daca valorile sunt valide, acestea sunt stocate intr-o matrice si returnate impreuna cu dimensiunile matricei.
Functia bac_eroziune() primeste ca argumente matricea si dimensiunea acesteia. Aceasta parcurge matricea si pentru fiecare element verifica daca este mai mic decat cel mai mic vecin. Daca este indeplinita aceasta conditie, se aduna o cantitate de nisip egala cu diferenta dintre valoarea celui mai mic vecin si valoarea curenta si se actualizeaza valoarea curenta. Cantitatea totala de nisip adaugata este returnata la sfarsit.
In if _name_ == '_main_':, se apeleaza functia citire_matrice() pentru a citi matricea de la utilizator si se afiseaza cantitatea totala de nisip adaugata prin apelarea functiei bac_eroziune().