2250 - Fact

De la Universitas MediaWiki

Enunt

Pentru un număr natural nenul, definim factorialul său ca fiind produsul tuturor numerelor naturale nenule mai mici sau egale decât el şi îl notăm N! (adică N! = 1*2*…*N). Pentru o bază de numeraţie B şi un număr natural nenul N, se cere determinarea ultimei cifre nenule a scrierii în baza B a lui N!.

Cerinţa

Se citesc 5 perechi de forma (Ni, Bi), unde 1 ≤ i ≤ 5. Pentru fiecare din cele 5 perechi citite, aflați ultima cifră nenulă a scrierii în baza Bi a factorialului numărului Ni.

Date de intrare

Fișierul de intrare fact.in conţine 5 linii, pe fiecare dintre ele fiind scrise câte două numere naturale nenule Ni şi Bi, scrise în baza 10, despărţite printr-un spaţiu.

Date de ieșire

Fișierul de ieșire fact.out va conţine 5 linii. Pe linia i se va afla cifra corespunzătoare unei perechi (Ni, Bi), citită de pe linia i din fişierul de intrare.

Restricţii şi precizări

  • 1 ≤ Ni ≤ 1.000.000, pentru 1 ≤ i ≤ 5
  • 2 ≤ Bi ≤ 36, pentru 1 ≤ i ≤ 5;
  • în cazul în care Bi > 10, cifrele mai mari decât 9 vor fi reprezentate prin litere mari ale alfabetului englez (10='A', 11='B', …, 35='Z');
  • un test va fi punctat doar dacă toate cele cinci rezultate cerute sunt corecte.

Exemplu

fact.in
5 10
7 10
7 20
8 16
9 8
fact.out
2
4
C
8
6


Explicație

5!=120, în baza 10, deci ultima cifră nenulă este 2 7!=5040, în baza 10, deci ultima cifră nenulă este 4 7!=CC0, în baza 20, deci ultima cifră nenulă este C 8!= 9D80, în baza 16, deci ultima cifră nenulă este 8 9!=1304600, în baza 8, deci ultima cifră nenulă este 6

Rezolvare

def last_nonzero_digit_factorial(N, B):
    # Calculează factorialul lui N
    factorial = 1
    for i in range(2, N + 1):
        factorial *= i

    # Convertim factorialul în baza B
    factorial_base_B = ""
    while factorial > 0:
        remainder = factorial % B
        if remainder >= 10:
            factorial_base_B = chr(ord('A') + remainder - 10) + factorial_base_B
        else:
            factorial_base_B = str(remainder) + factorial_base_B
        factorial //= B

    # Găsim ultima cifră nenulă
    for digit in reversed(factorial_base_B):
        if digit != '0':
            return digit

def main():
    # Citim datele de intrare
    with open("fact.in", "r") as fin:
        pairs = [list(map(int, line.split())) for line in fin.readlines()]

    # Determinăm ultima cifră nenulă pentru fiecare pereche
    results = [last_nonzero_digit_factorial(N, B) for N, B in pairs]

    # Scriem rezultatele în fișierul de ieșire
    with open("fact.out", "w") as fout:
        for result in results:
            fout.write(str(result) + "\n")

if __name__ == "__main__":
    main()