3206 - Nr Inversiuni: Difference between revisions
No edit summary |
|||
(5 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 | == 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 | *1 ⩽ n ⩽ 100.000 | ||
== Exemplul 1 == | == Exemplul 1 == | ||
;Intrare | ;Intrare | ||
:5 | |||
:4 2 5 1 3 | |||
;Iesire | ;Iesire | ||
:Datele introduse corespund restrictiilor impuse | |||
:6 | |||
== Exemplul 2 == | == Exemplul 2 == | ||
;Intrare | ;Intrare | ||
:5 | |||
:-2 8 0 3 | |||
;Iesire | ;Iesire | ||
:Datele introduse nu corespund restrictiilor impuse | |||
== Rezolvare == | == Rezolvare == | ||
<syntaxhighlight lang="python3" line="1"> | <syntaxhighlight lang="python3" line="1"> | ||
def | 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) | |||
return | 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__": | 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> | </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).