3064 - Copii 1

From Bitnami MediaWiki

Enunț[edit | edit source]

Iliuță și Pandele au învățat la școală operații aritmetice cu numere naturale. Astfel cei doi frați exersează operațiile folosindu-se de o tablă. Iliuță spune un număr natural X, iar Pandele scrie pe tablă rezultatul înmulțirii tuturor numerelor naturale de la 1 la X. Glumeț, Iliuță șterge cifrele egale cu 0 de la finalul numărului scris de Pandele. Ca să îl ierte, Pandele spune și el un număr natural Y și îi cere lui Iliuță să determine un număr natural Z care este cel mai mare divizor al lui Y având un număr impar de divizori.

Cerinţa[edit | edit source]

Cunoscându-se numerele spuse de copii, scrieți un program care rezolvă următoarele cerințe: 1) afișează ultimele K cifre ale produsului calculat de Pandele, după ștergerea cifrelor egale cu 0 de la finalul acestuia; 2) afișează numărul Z cu semnificația de mai sus și numărul de divizori ai acestuia.

Date de intrare[edit | edit source]

Fișierul de intrare copii.in conține pe prima linie numărul C, care reprezintă numărul cerinței și poate avea doar valorile 1 sau 2. Pentru prima cerință fișierul conține pe a doua linie numărul X, iar pe cea de a treia linie numărul K. Pentru a doua cerință fișierul conține pe a doua linie numărul Y.

Date de ieșire[edit | edit source]

Dacă datele sunt introduse corect, pe ecran se va afișa: "Datele sunt introduse corect.", apoi Pentru cerința 1), pe prima linie a fișierului copii.out se vor afișa cele K cifre cerute, fără spații, în ordine de la stânga la dreapta. Pentru cerința 2), pe prima linie se vor afișa, în această ordine, numărul Z determinat și numărul de divizori ai acestuia. Numerele vor fi separate printr-un spațiu. În cazul în care datele nu respectă restricțiile, se va afișa pe ecran: "Datele nu corespund restricțiilor impuse.".

Restricţii şi precizări[edit | edit source]

  • 1 ⩽ X ⩽ 1.000.000
  • 1 ⩽ Y ⩽ 1.000.000.000.000
  • 1 ⩽ K ⩽ 9
  • Numărul rămas după ștergerea zerourilor de la finalul produsului are cel puțin K cifre
  • Pentru rezolvarea primei cerințe se acordă 40 de puncte
  • Pentru rezolvarea primei cerințe se acordă 40 de puncte

Exemple[edit | edit source]

Exemplul 1[edit | edit source]

copii.in
1
12
3
copii.out
Datele sunt introduse corect.
016

Explicație[edit | edit source]

Produsul 1*2*3*4*5*6*7*8*9*10*11*12 = 479001600. După ștergerea zerourilor de la finalul produsului, ultimele 3 cifre sunt 016.

Exemplul 2:

Exemplul 2[edit | edit source]

copii.in
2
14641
copii.out
Datele sunt introduse corect.
14641 5

Explicație[edit | edit source]

Cel mai mare divizor al lui 14641 care are un număr impar de divizori este chiar 14641.

Rezolvare[edit | edit source]

<syntaxhighlight lang="python" line> def validare_date(c, x=None, y=None, k=None):

   if c not in [1, 2]:
       print("Datele nu corespund restricțiilor impuse.")
       return False
   
   if c == 1:
       if not (1 <= x <= 10**6 and 1 <= y <= 10**12 and 1 <= k <= 9):
           print("Datele nu corespund restricțiilor impuse.")
           return False
   elif c == 2:
       if not (1 <= y <= 10**12):
           print("Datele nu corespund restricțiilor impuse.")
           return False
   
   print("Datele sunt introduse corect.")
   return True


def produs_ultimele_k_cifre(x, k):

   product = 1
   for i in range(1, x+1):
       product *= i
       while product % 10 == 0:
           product //= 10
       product %= 10**k
   return product


def numar_divizori(n):

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


if __name__ == '__main__':

   with open('copii.in', 'r') as fin:
       c = int(fin.readline().strip())
       if c == 1:
           x = int(fin.readline().strip())
           k = int(fin.readline().strip())
           if not validare_date(c, x, k=k):
               exit()
           print(f"Produsul ultimelor {k} cifre ale lui {x}! este {produs_ultimele_k_cifre(x, k)}")
       elif c == 2:
           y = int(fin.readline().strip())
           if not validare_date(c, y=y):
               exit()
           divizori_count = produs_ultimele_k_cifre(y)
           max_divizor = 1
           for i in range(3, int(y**0.5) + 1, 2):
               while y % i == 0:
                   max_divizor *= i
                   y //= i
           if y > 2:
               max_divizor *= y
           print(f"Cel mai mare divizor al lui {y} cu un numar impar de divizori este {max_divizor} cu {divizori_count} divizori impari")
   with open('copii.out', 'w') as fout:
       if c == 1:
           fout.write(str(produs_ultimele_k_cifre(x, k)))
       elif c == 2:
           fout.write(f"{max_divizor} {divizori_count}")

</syntaxhighlight>