3206 - Nr Inversiuni: Difference between revisions

From Bitnami MediaWiki
Pagină nouă: Se dă șirul a1, a2, …, an care este o permutare a mulțimii {1, 2, ..., n}. O inversiune în permutare este o pereche (i, j) cu proprietatea că i < j și a[i] > a[j]. == Cerinta == Să se determine numărul inversiunilor permutării. == Date de intrare == Programul citește de la tastatură numărul n, iar apoi n numere naturale, separate prin spații, reprezentând permutarea. == Date de iesie == Programul va afișa pe ecran numărul S, reprezentând numărul inve...
 
 
(6 intermediate revisions by the same user not shown)
Line 1: Line 1:
Se dă șirul a1, a2, …, an care este o permutare a mulțimii {1, 2, ..., n}. O inversiune în permutare este o pereche (i, j) cu proprietatea că i < j și a[i] > a[j].
== Enunt ==
Se dă șirul '''a1, a2, …, an''' care este o permutare a mulțimii '''{1, 2, ..., n}'''. O '''inversiune''' în permutare este o pereche '''(i, j)''' cu proprietatea că '''i < j''' și '''a[i] > a[j]'''.


== Cerinta ==
== Cerinta ==
Line 7: Line 8:
== Date de intrare ==
== Date de intrare ==


Programul citește de la tastatură numărul n, iar apoi n numere naturale, separate prin spații, reprezentând permutarea.
Programul citește de la tastatură numărul '''n''', iar apoi '''n''' numere naturale, separate prin spații, reprezentând permutarea.


== Date de iesie ==
== Date de iesire ==


Programul va afișa pe ecran numărul S, reprezentând numărul inversiunilor permutării.
Programul va afișa pe ecran numărul '''S''', reprezentând numărul inversiunilor permutării.


== Restrictii si precizari ==
== Restrictii si precizari ==


*1 n 100.000
*1 &les; n &les; 100.000


== Exemplul 1
== Exemplul 1 ==
;Intrare
;Intrare
;5
:5
;4 2 5 1 3
:4 2 5 1 3
;Iesire
;Iesire
;Datele introduse corespund restrictiilor impuse
:Datele introduse corespund restrictiilor impuse
;6
:6


== Exemplul 2==
== Exemplul 2 ==
;Intrare
;Intrare
;4
:5
;-2 8 0 3
:-2 8 0 3
;Iesire
;Iesire
;Datele introduse nu corespund restrictiilor impuse
:Datele introduse nu corespund restrictiilor impuse


== Rezolvare ==
== Rezolvare ==
<syntaxhighlight lang="python3" line="1">
<syntaxhighlight lang="python3" line="1">
def numar_inversiuni_permutare(n, permutare):
def este_permutare_valida(n, permutare):
     numar_inversiuni = 0
     if n != len(permutare):
        return False


     for i in range(n - 1):
     elemente_unice = set(permutare)
        for j in range(i + 1, n):
    return len(elemente_unice) == n and all(1 <= elem <= n for elem in elemente_unice)
            if permutare[i] > permutare[j]:
                numar_inversiuni += 1


     return numar_inversiuni
def numara_inversiuni(arr):
     if len(arr) <= 1:
        return arr, 0


def main():
    mijloc = len(arr) // 2
     # Citirea datelor de intrare de la tastatură
     stanga, inversiuni_stanga = numara_inversiuni(arr[:mijloc])
    n = int(input("Introduceti numarul n: "))
     dreapta, inversiuni_dreapta = numara_inversiuni(arr[mijloc:])
     permutare = list(map(int, input(f"Introduceti permutarea de lungime {n}, separate prin spatiu: ").split()))


     # Calcularea numărului de inversiuni
     concatenat, inversiuni_split = combina_si_numara(stanga, dreapta)
    rezultat = numar_inversiuni_permutare(n, permutare)


     # Afișarea rezultatului
     inversiuni_totale = inversiuni_stanga + inversiuni_dreapta + inversiuni_split
     print(f"Numarul de inversiuni in permutare este: {rezultat}")
 
    return concatenat, inversiuni_totale
 
def combina_si_numara(stanga, dreapta):
    concatenat = []
    inversiuni_split = 0
    i = j = 0
 
    while i < len(stanga) and j < len(dreapta):
        if stanga[i] <= dreapta[j]:
            concatenat.append(stanga[i])
            i += 1
        else:
            concatenat.append(dreapta[j])
            inversiuni_split += len(stanga) - i
            j += 1
 
     concatenat.extend(stanga[i:])
    concatenat.extend(dreapta[j:])
 
    return concatenat, inversiuni_split


if __name__ == "__main__":
if __name__ == "__main__":
     main()
     n = int(input("Introduceți numărul n: "))
    permutare = list(map(int, input("Introduceți permutarea: ").split()))
 
    if este_permutare_valida(n, permutare):
        _, inversiuni = numara_inversiuni(permutare)
        print("Numărul inversiunilor permutării:", inversiuni)
    else:
        print("Permutarea introdusă nu este validă.")
 
 
</syntaxhighlight>
</syntaxhighlight>


== Explicatie ==
== Explicatie ==
Cele 6 inversiuni sunt date de perechile de indici (1,2), (1,4), (1,5), (2,4), (3,4), (3,5).
Cele 6 inversiuni sunt date de perechile de indici (1,2), (1,4), (1,5), (2,4), (3,4), (3,5).

Latest revision as of 11:23, 29 December 2023

Enunt[edit | edit source]

Se dă șirul a1, a2, …, an care este o permutare a mulțimii {1, 2, ..., n}. O inversiune în permutare este o pereche (i, j) cu proprietatea că i < j și a[i] > a[j].

Cerinta[edit | edit source]

Să se determine numărul inversiunilor permutării.

Date de intrare[edit | edit source]

Programul citește de la tastatură numărul n, iar apoi n numere naturale, separate prin spații, reprezentând permutarea.

Date de iesire[edit | edit source]

Programul va afișa pe ecran numărul S, reprezentând numărul inversiunilor permutării.

Restrictii si precizari[edit | edit source]

  • 1 ⩽ n ⩽ 100.000

Exemplul 1[edit | edit source]

Intrare
5
4 2 5 1 3
Iesire
Datele introduse corespund restrictiilor impuse
6

Exemplul 2[edit | edit source]

Intrare
5
-2 8 0 3
Iesire
Datele introduse nu corespund restrictiilor impuse

Rezolvare[edit | edit source]

<syntaxhighlight lang="python3" line="1"> def este_permutare_valida(n, permutare):

   if n != len(permutare):
       return False
   elemente_unice = set(permutare)
   return len(elemente_unice) == n and all(1 <= elem <= n for elem in elemente_unice)

def numara_inversiuni(arr):

   if len(arr) <= 1:
       return arr, 0
   mijloc = len(arr) // 2
   stanga, inversiuni_stanga = numara_inversiuni(arr[:mijloc])
   dreapta, inversiuni_dreapta = numara_inversiuni(arr[mijloc:])
   concatenat, inversiuni_split = combina_si_numara(stanga, dreapta)
   inversiuni_totale = inversiuni_stanga + inversiuni_dreapta + inversiuni_split
   return concatenat, inversiuni_totale

def combina_si_numara(stanga, dreapta):

   concatenat = []
   inversiuni_split = 0
   i = j = 0
   while i < len(stanga) and j < len(dreapta):
       if stanga[i] <= dreapta[j]:
           concatenat.append(stanga[i])
           i += 1
       else:
           concatenat.append(dreapta[j])
           inversiuni_split += len(stanga) - i
           j += 1
   concatenat.extend(stanga[i:])
   concatenat.extend(dreapta[j:])
   return concatenat, inversiuni_split

if __name__ == "__main__":

   n = int(input("Introduceți numărul n: "))
   permutare = list(map(int, input("Introduceți permutarea: ").split()))
   if este_permutare_valida(n, permutare):
       _, inversiuni = numara_inversiuni(permutare)
       print("Numărul inversiunilor permutării:", inversiuni)
   else:
       print("Permutarea introdusă nu este validă.")


</syntaxhighlight>

Explicatie[edit | edit source]

Cele 6 inversiuni sunt date de perechile de indici (1,2), (1,4), (1,5), (2,4), (3,4), (3,5).