0780 - Cmmdc Sum

De la Universitas MediaWiki

Cerinţa

Se dă o matrice cu n linii şi n coloane şi elemente numere naturale. Calculaţi cel mai mare divizor comun al sumei elementelor de deasupra diagonalei principale și al sumei elementelor de sub diagonala principală.

Date de intrare

Programul citește de la tastatură numărul n, iar apoi n*n numere naturale, separate prin spaţii, reprezentând elementele matricei, linie cu linie.

Date de ieşire

Dacă datele sunt introduse corect,pe ecran se va afișa :"Datele sunt introduse corect.",apoi pe un rând nou numărul D, reprezentând valoarea calculată.În cazul contrar,se va afișa pe ecran "Datele nu corespund restricțiilor impuse.".

Restricții și precizări

  • 1 ⩽ n ⩽ 20
  • elementele matricei vor fi mai mici decât 1.000.000
  • cel puţin un element situat deasupra diagnalei principale şi cel puţin un element situat sub diagonala principală sunt nenule

Exemplu

Date de intrare
4
8 3 5 6
5 5 6 5
3 8 6 5
8 4 8 8
Date de ieșire
Datele sunt introduse corect.
6

Explicație

Suma elementelor de sub diagonala principală este 36 iar cea a elementelor de deasupra diagonalei principale este 30. Cel mai mare divizor comun pentru 36 şi 30 este 6.

Rezolvare

def validare(n: int, a: list) -> str:
    # Verificăm dacă numărul de linii și de coloane este mai mare sau egal cu 1 și mai mic sau egal cu 20
    if n < 1 or n > 20:
        return False

    # Verificăm dacă fiecare element al matricei este mai mic decât 1.000.000
    for i in range(n):
        for j in range(n):
            if a[i][j] >= 1000000:
                return False

    # Verificăm dacă există cel puțin un element nenul deasupra diagonalei principale și unul sub diagonala principală
    deasupra = False
    sub = False
    for i in range(n):
        for j in range(n):
            if i < j and a[i][j] != 0:
                deasupra = True
            if i > j and a[i][j] != 0:
                sub = True
    if not deasupra or not sub:
        return False

    # Dacă toate restricțiile sunt respectate, returnăm un mesaj de confirmare
    return True


# Funcția de calculare a celui mai mare divizor comun
def calculeaza_cel_mai_mare_divizor_comun(n: int, a: list) -> int:
    sum_deasupra = 0
    sum_sub = 0
    # Parcurgem matricea și calculăm sumele elementelor situate deasupra și sub diagonala principală
    for i in range(n):
        for j in range(n):
            if i < j:
                sum_deasupra += a[i][j]
            elif i > j:
                sum_sub += a[i][j]
    # Verificăm care dintre cele doua sume este mai mare si aplicăm algoritmul Euclid pentru a calcula cel mai mare divizor comun
    if sum_deasupra < sum_sub:
        sum_deasupra, sum_sub = sum_sub, sum_deasupra
    while sum_deasupra % sum_sub != 0:
        rest = sum_deasupra % sum_sub
        sum_deasupra = sum_sub
        sum_sub = rest
    # Returnăm cel mai mare divizor comun
    return sum_sub

if __name__ == '__main__':
        # Citim numărul de linii și coloane al matricei
        n = int(input())
        # Citim matricea
        a = []
        for i in range(n):
            a.append(list(map(int, input().split())))

        # Verificăm dacă matricea respectă restricțiile impuse
        if validare(n, a) :
            print("\nDatele sunt introduse corect.\n")
            # Calculăm cel mai mare divizor comun și îl afișăm
            D = calculeaza_cel_mai_mare_divizor_comun(n, a)
            print(D)
        else:
            print("Datele nu corespund restrictiilor impuse.")