3302 - Sum Inv Div

De la Universitas MediaWiki

Cerinţa

Pe prima linie a fișierului suminvdiv.in se găsesc cel mult 1000 de numere naturale distincte mai mici decât 10.000.000.000. Scrieți un program care determină pentru fiecare număr citit x suma s=1/d1+1/d2+..+1/di , unde d1,d2,….,di sunt divizorii numărului x. Valorile determinate se vor afișa separate printr-un spațiu.

Date de intrare

Fișierul de intrare suminvdiv.in conține pe prima linie cel mult 1000 de numere naturale distincte mai mici decât 10.000.000.000 separate prin spații.

Date de ieşire

Fișierul de ieșire suminvdiv.out va conține pe prima linie valorile determinate cu exact 2 zecimale pentru fiecare număr x din fișierul de intrare, valori separate printr-un spațiu.

Restricții și precizări

  • pe prima linie a fișierului sunt cel mult 1000 de numere
  • numerele de pe prima linie a fișierului de intrare sunt mai mici decât 10.000.000.000
  • rezultatul este considerat corect dacă diferența dintre fiecare valoare afișată și cea corectă este mai mică decât 0.

Exemplu

suminvdiv.in
12 9 123 78 34 278313 349012 6 24242 900000
suminvdiv.out
2.33 1.44 1.37 2.15 1.59 1.58 1.75 2.00 1.71 3.55

Explicație

  • Divizorii lui 12 sunt: 1, 2, 3, 4, 6 și 12……s=(11+12+13+14+16+112)=2.33
  • Divizorii lui 9 sunt: 1, 3 și 9……s=(11+13+19)=1.44, etc.


Rezolvare

import math
import os

def validare_date(nums):
    # Verifică dacă numerele sunt mai mici de 10 miliarde
    for num in nums:
        if num >= 10000000000:
            return False
    return True

if __name__ == '__main__':
    # Verifică dacă fișierul de intrare există
    if not os.path.isfile('suminvdiv.in'):
        print("Fișierul de intrare nu există")
        exit()

    # Citeste numerele din fișier
    with open('suminvdiv.in', 'r') as f:
        nums = [int(x) for x in f.readline().split()]

    # Validează datele de intrare
    if validare_date(nums):
        print("\nDatele de intrare corespund restricțiilor impuse.\n")
        # Parcurge fiecare număr și calculează suma inverselor divizorilor
        results = []
        for num in nums:
            divisors_sum = 0
            limit = int(math.sqrt(num))
            for i in range(1, limit+1):
                if num % i == 0:
                    divisors_sum += 1/i
                    if i != num // i:
                        divisors_sum += 1/(num//i)
            results.append(divisors_sum)

        # Afișează rezultatele în fișier
        with open('suminvdiv.out', 'w') as f:
            f.write(' '.join(f'{result:.2f}' for result in results))
    else:
        print("Datele de intrare nu corespund restricțiilor impuse.")

Explicație rezolvare

Acest cod rezolvă o problemă care implică citirea unui set de numere dintr-un fișier de intrare, validarea acestora și calcularea sumei inverselor divizorilor pentru fiecare număr. Rezultatele sunt afișate cu două zecimale și scrise într-un fișier de ieșire.