Cod sursa(job #2673688)

Utilizator mariusn01Marius Nicoli mariusn01 Data 17 noiembrie 2020 15:50:52
Problema Factorial Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.64 kb
#include <fstream>
#include <iostream>
using namespace std;
long long st, dr, mid, p;
/**
Se stie ca pentru fiecare moment d la 1 la n
functia verif(moment) returneaza mai intai 0
de la 0 la o valoare k iar pentru moment
de la k+1 la n functia va returna 1

verif(1) =   0
verif(2) =   0
verif(3) =   0
...
verif(k-1) = 0
verif(k) =   1
verif(k+1) = 1
verif(k+2) = 1
...
verif(n) =   1

Noi am observat ca se intampla asta si trebuie sa aflam k
**/

int zeronf(int n) {
    /// cate zerouri sunt la finalul lui n!
    /**
    132! = cati factori primi 5 au in total aceste numere
    132/5 = atatea numere sunt divizibile cu 5
    + 132/25 = numar al doilea 5 de la 25, 50, 75, 100, 125
    + 132/125
    **/
    int p = 5;
    int sol = 0;
    while (p <= n) {
        sol += n/p;
        p*=5;
    }
    return sol;
}


int main  () {
    ifstream fin ("fact.in");
    ofstream fout("fact.out");
    fin>>p;
    /**
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
    0 0 0 0 1 1 1 1 1  2  2  2  2  2  3  3  3  3  3  4  4  4  4  4  6
    notam zeronf(n) = numarul de zerouri de la finalul lui n!
    daca i<j atunci zeronf(i) <= zeronf(j)
    dat p, trebuie sa gasesc cel mai mic k ai zeronf(k) >= p
    **/

    st = 1;
    dr = 5*p;

    ///zeronf(dr) = 5*p/5 + 5*p/25 + 5*p/

    while (st<=dr) {
        int mid = (st + dr)/2;
        ///calculez rez = zeronf(mid). ce decizie iau in functie de rez ?
        if (zeronf(mid) >= p)
            dr = mid-1;
        else
            st = mid+1;
    }
    if (zeronf(st) == p)
        fout<<st;
    else
        fout<<-1;

}