3410 - Submatrix Sum Max

De la Universitas MediaWiki
Versiunea pentru tipărire nu mai este suportată și poate avea erori de randare. Vă rugăm să vă actualizați bookmarkurile browserului și să folosiți funcția implicită de tipărire a browserului.

Se dă o matrice de numere întregi cu n linii și n coloane.

Cerință

Se dă o matrice de numere întregi cu n linii și n coloane. Să se determine suma maximă care se poate obține dintr-o submatrice.

Date de intrare

Programul citește de la tastatură numărul n, iar apoi elementele matricei cu n linii și n coloane.

Date de ieșire

Programul va afișa pe ecran suma maximă care se poate obține dintr-o submatrice.

Restricții de precizări

  • 1 ⩽ n ⩽ 300
  • Elementele matricei sunt numere întregi din intervalul [-1000, 1000]
  • O submatrice poate fi formată dintr-un singur element

Exemplul 1

Intrare
5
2 4 -1 2 -1
4 -7 1 -6 -1
-9 2 4 5 -7
1 3 -2 6 2
1 -4 -6 -5 8
Ieșire
Datele introduse corespund restricțiilor impuse.
18

Exemplul 2

Intrare
1x
Ieșire
Datele introduse nu corespund restricțiilor impuse.

Rezolvare

def verificare_restrictii(numar, matrix):    # functia de verificare a datelor de intrare
    if 1 <= numar <= 300 and all(-1000 <= element <= 1000 for rand in matrix for element in rand):
        return True
    else:
        return False


def suma_maxima_submatrice(numar, matrix):
    # inițializăm matricea de sume prefix cu 0
    prefix_sum = [[0 for _ in range(numar + 1)] for _ in range(numar + 1)]

    # calculăm matricea de sume prefix
    for i in range(numar):
        for j in range(numar):
            prefix_sum[i + 1][j + 1] = matrix[i][j] - prefix_sum[i][j] + prefix_sum[i][j + 1] + prefix_sum[i + 1][j]

    max_sum = float('-inf')  # inițializăm suma maximă cu -infinit
    # parcurgem toate submatricile posibile
    for i in range(1, numar + 1):
        for j in range(1, numar + 1):
            for k in range(i, numar + 1):
                for lenght in range(j, numar + 1):
                    # calculăm suma submatricei curente folosind sumele prefix
                    curr_sum = prefix_sum[k][lenght] - prefix_sum[k][j - 1] - prefix_sum[i - 1][lenght] + prefix_sum[i - 1][j - 1]
                    max_sum = max(max_sum, curr_sum)  # actualizăm suma maximă dacă este cazul

    return max_sum  # returnăm suma maximă


if __name__ == '__main__':
    try:
        n = int(input("Introduceti numarul de linii/coloane: "))     # citirea numarului de linii si coloane
        matrice = [list(map(int, input().split())) for _ in range(n)]  # citirea matricei

        if verificare_restrictii(n, matrice):             # verificam datele de intrare
            print("Datele de intrare corespund restrictiilor impuse.")
            print(suma_maxima_submatrice(n, matrice))  # apelam functia de rezolvare
        else:
            print("Datele de intrare nu corespund restrictiilor impuse.")
    # ne asteptam la 2 tipuri de erori din cauza datelor de intrare, le tratam corespunzator
    except ValueError:
        print("Datele de intrare nu corespund restrictiilor impuse.")
    except IndexError:
        print("Datele de intrare nu corespund restrictiilor impuse.")

Explicație

Submatricea de sumă maximă este:

2 4 5
3 -2 6