3680 - Numere X

From Bitnami MediaWiki

Enunţ

Pentru un număr natural nenul X, se numește divizor propriu al lui X, un divizor natural al lui X, diferit de 1 și X. De exemplu, pentru numărul 20 divizorii proprii sunt 2, 4, 5, 10, iar numărul 20 are 4 divizori proprii.

Cerința

1. Se dă un număr natural N. Determinați cel mai mic număr din intervalul închis [1,N] care are număr maxim de divizori proprii. 2. Se dau trei numere N, M și T. Determinați câte intervale de forma [a,b] au proprietatea că există exact M numere naturale care au T divizori proprii.

Date de intrare

Fișierul de intrare numere.in conține pe prima linie un număr natural P reprezentând cerința din problemă care trebuie rezolvată.

Dacă P = 1 atunci pe a doua linie se găsește un număr natural N, reprezentând extremitatea din dreapta a intervalului.

Dacă P = 2 atunci pe a doua linie se găsesc trei numere: un număr natural N, un număr natural M și un număr natural T cu semnificațiile din enunț.

Date de ieșire

Dacă P = 1 atunci fișierul de ieșire numere.out conține pe o singură linie numărul cel mai mic determinat care are număr maxim de divizori.

Dacă P = 2 atunci fișierul de ieșire numere.out conține pe o singură linie numărul de intervale determinate care au proprietatea cerută.

Restricții și precizări

  • 1 ≤ N ≤ 100000
  • 1 ≤ M ≤ 100000
  • 1 ≤ T ≤ 100000
  • 1 ≤ a ≤ b ≤ N

Exemplul 1

numere.in
1
20
numere.out
12

Explicație

12 are 4 divizori proprii și este cel mai mic număr cu 4 divizori proprii din [1,20].

Exemplul 2

numere.in
2
10 3 2
numere.out
6

Explicație

[1,10], [2,10], [3,10], [4,10], [5,10], [6,10] sunt cele 6 intervale în care se găsesc exact 3 numere cu 2 divizori proprii(6, 8, 10 sunt numerele cu 3 divizori proprii).

Exemplul 3

numere.in
1
0
numere.out
Datele introduse sunt invalide

Rezolvare

<syntaxhighlight lang="python" line>

  1. 3680 - Numere X

def numar_divizori(n):

   divizori = 0
   for i in range(2, int(n**0.5) + 1):
       if n % i == 0:
           if n // i == i:
               divizori += 1
           else:
               divizori += 2
   return divizori

def cel_mai_mic_numar_cu_max_divizori(N):

   maxim_divizori = 0
   numar = 0
   for i in range(1, N + 1):
       divizori = numar_divizori(i)
       if divizori > maxim_divizori:
           maxim_divizori = divizori
           numar = i
   return numar

def numar_intervale_cu_M_numere_T_divizori(N, M, T):

   numar_intervale = 0
   for a in range(1, N + 1):
       for b in range(a, N + 1):
           numere_cu_T_divizori = sum(1 for x in range(a, b + 1) if numar_divizori(x) == T)
           if numere_cu_T_divizori == M:
               numar_intervale += 1
   return numar_intervale

def verifica_date_intrare(P, N, M, T):

   if P not in [1, 2]:
       return False
   if P == 1:
       if not isinstance(N, int) or N < 1 or N > 100000:
           return False
   elif P == 2:
       if not (isinstance(N, int) and isinstance(M, int) and isinstance(T, int)):
           return False
       if not (1 <= N <= 100000 and 1 <= M <= 100000 and 1 <= T <= 100000):
           return False
   return True

def main():

   N = None
   with open("numere.in", "r") as fin:
       P = int(fin.readline().strip())
       if P == 1:
           N = int(fin.readline().strip())
       elif P == 2:
           N, M, T = map(int, fin.readline().strip().split())
   if not verifica_date_intrare(P, N, M if P == 2 else None, T if P == 2 else None):
       with open("numere.out", "w") as fout:
           fout.write("Datele introduse sunt invalide\n")
       return
   if P == 1:
       rezultat = cel_mai_mic_numar_cu_max_divizori(N)
   else:
       rezultat = numar_intervale_cu_M_numere_T_divizori(N, M, T)
   with open("numere.out", "w") as fout:
       fout.write(str(rezultat) + "\n")

if __name__ == "__main__":

   main()

</syntaxhighlight>