2905 - Divizori 4: Difference between revisions

From Bitnami MediaWiki
Pagină nouă: == Cerinţa == Gigel a găsit un șir cu n numere naturale, numerotate de la '''1''' la '''n''' și un număr '''p'''. Neavând chef de muncă, Gigel vă cere să rezolvați următoarele cerințe: a) Aflați câți divizori are numărul din șir aflat pe poziția '''p'''. b) Afișați în ordine descrescătoare numerele din șir care au același număr de divizori ca cel aflat pe poziția '''p'''. == Date de intrare == Fișierul de intrare '''divizori4.in''' conține pe prim...
 
No edit summary
 
Line 5: Line 5:
b) Afișați în ordine descrescătoare numerele din șir care au același număr de divizori ca cel aflat pe poziția '''p'''.
b) Afișați în ordine descrescătoare numerele din șir care au același număr de divizori ca cel aflat pe poziția '''p'''.
== Date de intrare ==
== Date de intrare ==
Fișierul de intrare '''divizori4.in''' conține pe prima linie numerele '''n c''', unde c poate fi doar '''1''' sau '''2'''. A doua linie conține cele '''n''' elemente ale șirului. A treia linie conține numărul '''p'''.
Fișierul de intrare '''divizori4in.txt''' conține pe prima linie numerele '''n c''', unde c poate fi doar '''1''' sau '''2'''. A doua linie conține cele '''n''' elemente ale șirului. A treia linie conține numărul '''p'''.
== Date de ieşire ==
== Date de ieşire ==
Dacă '''c=1''' se rezolvă numai cerința a). Fișierul de ieșire '''divizori4.out''' va conține pe prima linie numărul de divizori ai numărului aflat în șir pe poziția '''p'''.
Dacă '''c=1''' se rezolvă numai cerința a). Fișierul de ieșire '''divizori4out.txt''' va conține pe prima linie numărul de divizori ai numărului aflat în șir pe poziția '''p'''.


Dacă '''c=2''' se rezolvă numai cerința b). Fișierul de ieșire '''divizori4.out''' va conține pe prima linie, în ordine descrescătoare, numerele din șir cu același număr de divizori ca și cel aflat pe poziția '''p'''.
Dacă '''c=2''' se rezolvă numai cerința b). Fișierul de ieșire '''divizori4out.txt''' va conține pe prima linie, în ordine descrescătoare, numerele din șir cu același număr de divizori ca și cel aflat pe poziția '''p'''.
== Restricții și precizări ==
== Restricții și precizări ==
* numerele din șir vor fi numere naturale nenule mai mici sau egale cu '''1.000.000.000'''
* numerele din șir vor fi numere naturale nenule mai mici sau egale cu '''1.000.000.000'''
Line 16: Line 16:
* pentru '''c=2''', '''1 ≤ p ≤ n ≤ 50.000''' pentru 30% din punctaj și '''1 ≤ p ≤ n ≤ 10.000''' pentru 20% din punctaj
* pentru '''c=2''', '''1 ≤ p ≤ n ≤ 50.000''' pentru 30% din punctaj și '''1 ≤ p ≤ n ≤ 10.000''' pentru 20% din punctaj
== Exemplul 1 ==
== Exemplul 1 ==
; divizori4.in
; divizori4in.txt
: 10 1
: 10 1
: 1 5 95 23 16 39 77 74 97 57  
: 1 5 95 23 16 39 77 74 97 57  
: 3
: 3
; divizori4.out
; divizori4out.txt
: Datele introduse corespund restricțiilor impuse.
: 4
: 4
== Explicație ==
== Explicație ==
'''c=1''', se rezolvă doar cerința a). Al treilea număr din șir este '''95''', care are '''4''' divizori '''(1 5 19 95)'''.
'''c=1''', se rezolvă doar cerința a). Al treilea număr din șir este '''95''', care are '''4''' divizori '''(1 5 19 95)'''.
== Exemplul 2 ==
== Exemplul 2 ==
; divizori4.in
; divizori4in.txt
: 10 2
: 10 2
: 1 5 95 23 16 39 77 74 97 57  
: 1 5 95 23 16 39 77 74 97 57  
: 3
: 3
; divizori4.out
; divizori4out.txt
: Datele introduse corespund restricțiilor impuse.
: 95 77 74 57 39
: 95 77 74 57 39
== Explicație ==
== Explicație ==
'''c=2''', se rezolvă doar cerința b). Al treilea număr din șir este '''95''', care are '''4''' divizori. Numerele cu '''4''' divizori din șir sunt, în ordine descrescătoare: '''95 77 74 57 39'''.
'''c=2''', se rezolvă doar cerința b). Al treilea număr din șir este '''95''', care are '''4''' divizori. Numerele cu '''4''' divizori din șir sunt, în ordine descrescătoare: '''95 77 74 57 39'''.
== Exemplul 3 ==
; divizori4in.txt
: 10 1
: 1 2 3 4 5 6 7 8 9 1000000001
: 5
; divizori4out.txt
: Datele introduse nu corespund restricțiilor impuse.
== Rezolvare ==
== Rezolvare ==
<syntaxhighlight lang="python" line>
<syntaxhighlight lang="python" line>
import math
# 2905 - Divizori 4
def validare(serie_validare):
    # Verificam daca numarul de elemente din serie este mai mare decat 50_000
    # Daca este, aruncam o exceptie ValueError
    if len(serie_validare) > 50_000:
        raise ValueError


# Funcția care calculează numărul de divizori ai unui număr
     for numar in serie_validare:
def numar_divizori(n):
         if not (1 <= numar <= 1_000_000_000):
    num_divizori = 0
             raise ValueError
     for i in range(1, int(math.sqrt(n)) + 1):
         if n % i == 0:
            if n / i == i:
                num_divizori += 1
             else:
                num_divizori += 2
    return num_divizori


def rezolva_problema(input_file, output_file, c):
     # Daca datele de intrare sunt valide, afisam un mesaj in fisierul de iesire
     # Deschidem fișierul de intrare și citim datele
    fisier_iesire.write("Datele de intrare corespund restrictiilor impuse\n")
    with open(input_file, 'r') as fisier:
        n, c = map(int, fisier.readline().split())  # Citim n și c
        sir = [int(numar) for numar in fisier.readline().split()]  # Citim șirul de numere
        p = int(fisier.readline())  # Citim p


     # Deschidem fișierul de ieșire pentru a scrie rezultatul
 
     with open(output_file, 'w') as fisier:
def numar_divizori(n_divizori):
         if c == 1:
    i = 1
             # Afișăm numărul de divizori ai numărului de pe poziția p
    rezultat = 0
             fisier.write(str(numar_divizori(sir[p-1])))
     # Parcurgem numerele de la 1 la radacina patrata a numarului
     while i * i <= n_divizori:
        # Daca numarul nu este divizor, incrementam i
         if n_divizori % i:
            i += 1
             continue
        # Daca i este divizor, il adaugam la rezultat
        # Daca i * i este egal cu numarul, adaugam doar o data i la rezultat
        # Altfel, adaugam si i si numarul / i la rezultat
        if i * i == n_divizori:
             rezultat += 1
         else:
         else:
             # Afișăm numerele din șir care au același număr de divizori ca numărul de pe poziția p
             rezultat += 2
            num_divizori_p = numar_divizori(sir[p-1])
        i += 1
            numere = sorted((numar for numar in sir if numar_divizori(numar) == num_divizori_p), reverse=True)
    return rezultat
            fisier.write(' '.join(str(numar) for numar in numere))
 
 
def divizori4(serie_divizori4, pozitie_divizori4, cerinta_divizori4):
    # Luam numarul de pe pozitia data
    numar = serie_divizori4[pozitie_divizori4-1]
    # Calculam numarul de divizori ai numarului
    divizori_numar = numar_divizori(numar)
 
    # Daca cerinta este 1, afisam numarul de divizori al numarului
    if cerinta_divizori4 == 1:
        fisier_iesire.write(str(divizori_numar))
    else:
        # Daca cerinta este 2, afisam numerele din serie care au acelasi numar de divizori ca numarul de pe pozitia data
        numere_cu_acelasi_nr_divizori = [x for x in serie_divizori4 if numar_divizori(x) == divizori_numar]
        # Sortam numerele in ordine descrescatoare
        numere_cu_acelasi_nr_divizori.sort(reverse=True)
        # Afisam numerele
        fisier_iesire.write(' '.join(map(str, numere_cu_acelasi_nr_divizori)))
 
 
if __name__ == '__main__':
    # Deschidem fisierele de intrare si iesire
    fisier_intrare = open("divizori4in.txt", "r")
    fisier_iesire = open("divizori4out.txt", "w")
 
    try:
        n_main, cerinta_main = map(int, fisier_intrare.readline().split())
        serie_main = list(map(int, fisier_intrare.readline().split()))
        pozitie_main = int(fisier_intrare.readline())
 
        # Validam datele de intrare
        validare(serie_main)
        # Rezolvam problema
        divizori4(serie_main, pozitie_main, cerinta_main)


if __name__ == "__main__":
    # Tratam exceptiile care pot aparea
    rezolva_problema('divizori4.in', 'divizori4.out', 1)
    except ValueError:
     rezolva_problema('divizori4.in', 'divizori4.out', 2)
        fisier_iesire.write("Datele de intrare nu corespund restrictiilor impuse")
     except IndexError:
        fisier_iesire.write("Datele de intrare nu corespund restrictiilor impuse")


</syntaxhighlight>
</syntaxhighlight>

Latest revision as of 22:23, 11 December 2023

Cerinţa[edit | edit source]

Gigel a găsit un șir cu n numere naturale, numerotate de la 1 la n și un număr p. Neavând chef de muncă, Gigel vă cere să rezolvați următoarele cerințe:

a) Aflați câți divizori are numărul din șir aflat pe poziția p. b) Afișați în ordine descrescătoare numerele din șir care au același număr de divizori ca cel aflat pe poziția p.

Date de intrare[edit | edit source]

Fișierul de intrare divizori4in.txt conține pe prima linie numerele n c, unde c poate fi doar 1 sau 2. A doua linie conține cele n elemente ale șirului. A treia linie conține numărul p.

Date de ieşire[edit | edit source]

Dacă c=1 se rezolvă numai cerința a). Fișierul de ieșire divizori4out.txt va conține pe prima linie numărul de divizori ai numărului aflat în șir pe poziția p.

Dacă c=2 se rezolvă numai cerința b). Fișierul de ieșire divizori4out.txt va conține pe prima linie, în ordine descrescătoare, numerele din șir cu același număr de divizori ca și cel aflat pe poziția p.

Restricții și precizări[edit | edit source]

  • numerele din șir vor fi numere naturale nenule mai mici sau egale cu 1.000.000.000
  • pentru 50% din punctaj c=1; pentru 50% din punctaj c=2;
  • pentru c=1, 1 ≤ p ≤ n ≤ 50.000
  • pentru c=2, 1 ≤ p ≤ n ≤ 50.000 pentru 30% din punctaj și 1 ≤ p ≤ n ≤ 10.000 pentru 20% din punctaj

Exemplul 1[edit | edit source]

divizori4in.txt
10 1
1 5 95 23 16 39 77 74 97 57
3
divizori4out.txt
Datele introduse corespund restricțiilor impuse.
4

Explicație[edit | edit source]

c=1, se rezolvă doar cerința a). Al treilea număr din șir este 95, care are 4 divizori (1 5 19 95).

Exemplul 2[edit | edit source]

divizori4in.txt
10 2
1 5 95 23 16 39 77 74 97 57
3
divizori4out.txt
Datele introduse corespund restricțiilor impuse.
95 77 74 57 39

Explicație[edit | edit source]

c=2, se rezolvă doar cerința b). Al treilea număr din șir este 95, care are 4 divizori. Numerele cu 4 divizori din șir sunt, în ordine descrescătoare: 95 77 74 57 39.

Exemplul 3[edit | edit source]

divizori4in.txt
10 1
1 2 3 4 5 6 7 8 9 1000000001
5
divizori4out.txt
Datele introduse nu corespund restricțiilor impuse.

Rezolvare[edit | edit source]

<syntaxhighlight lang="python" line>

  1. 2905 - Divizori 4

def validare(serie_validare):

   # Verificam daca numarul de elemente din serie este mai mare decat 50_000
   # Daca este, aruncam o exceptie ValueError
   if len(serie_validare) > 50_000:
       raise ValueError
   for numar in serie_validare:
       if not (1 <= numar <= 1_000_000_000):
           raise ValueError
   # Daca datele de intrare sunt valide, afisam un mesaj in fisierul de iesire
   fisier_iesire.write("Datele de intrare corespund restrictiilor impuse\n")


def numar_divizori(n_divizori):

   i = 1
   rezultat = 0
   # Parcurgem numerele de la 1 la radacina patrata a numarului
   while i * i <= n_divizori:
       # Daca numarul nu este divizor, incrementam i
       if n_divizori % i:
           i += 1
           continue
       # Daca i este divizor, il adaugam la rezultat
       # Daca i * i este egal cu numarul, adaugam doar o data i la rezultat
       # Altfel, adaugam si i si numarul / i la rezultat
       if i * i == n_divizori:
           rezultat += 1
       else:
           rezultat += 2
       i += 1
   return rezultat


def divizori4(serie_divizori4, pozitie_divizori4, cerinta_divizori4):

   # Luam numarul de pe pozitia data
   numar = serie_divizori4[pozitie_divizori4-1]
   # Calculam numarul de divizori ai numarului
   divizori_numar = numar_divizori(numar)
   # Daca cerinta este 1, afisam numarul de divizori al numarului
   if cerinta_divizori4 == 1:
       fisier_iesire.write(str(divizori_numar))
   else:
       # Daca cerinta este 2, afisam numerele din serie care au acelasi numar de divizori ca numarul de pe pozitia data
       numere_cu_acelasi_nr_divizori = [x for x in serie_divizori4 if numar_divizori(x) == divizori_numar]
       # Sortam numerele in ordine descrescatoare
       numere_cu_acelasi_nr_divizori.sort(reverse=True)
       # Afisam numerele
       fisier_iesire.write(' '.join(map(str, numere_cu_acelasi_nr_divizori)))


if __name__ == '__main__':

   # Deschidem fisierele de intrare si iesire
   fisier_intrare = open("divizori4in.txt", "r")
   fisier_iesire = open("divizori4out.txt", "w")
   try:
       n_main, cerinta_main = map(int, fisier_intrare.readline().split())
       serie_main = list(map(int, fisier_intrare.readline().split()))
       pozitie_main = int(fisier_intrare.readline())
       # Validam datele de intrare
       validare(serie_main)
       # Rezolvam problema
       divizori4(serie_main, pozitie_main, cerinta_main)
   # Tratam exceptiile care pot aparea
   except ValueError:
       fisier_iesire.write("Datele de intrare nu corespund restrictiilor impuse")
   except IndexError:
       fisier_iesire.write("Datele de intrare nu corespund restrictiilor impuse")

</syntaxhighlight>