Cod sursa(job #2251914)

Utilizator gabrielmGabriel Majeri gabrielm Data 2 octombrie 2018 09:32:20
Problema Factorial Scor 10
Compilator c Status done
Runda Arhiva de probleme Marime 1.05 kb
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

// Returneaza numarul de zerouri in `n!`,
// fara sa calculeze numarul in sine
uint64_t fact_zero(uint64_t n) {
  // 0-urile apar fie din termenii `2 * 5`,
  // fie din `10` sau multiplii de `10`.

  uint64_t z = 0;

  for (uint64_t i = 5; i <= n; i *= 5) {
    z += n / i;
  }

  return z;
}

// Cauta binar intre `st` si `dr` numarul minim
// pentru care `n!` are exact `z` zerouri.
uint64_t cauta(uint64_t z, uint64_t st, uint64_t dr) {
  if (st > dr) {
    return 0;
  }

  uint64_t m = st + (dr - st) / 2;

  uint64_t nr_zero = fact_zero(m);

  // Bingo
  if (nr_zero == z) {
    while (fact_zero(--m) == z)
      ;
    return m + 1;
  } else if (nr_zero < z) {
    // Nu avem destule zero-uri
    return cauta(z, m, dr);
  } else {
    // Prea multe zero-uri
    return cauta(z, st, m);
  }
}

int main() {
  // Fisiere I/O
  FILE* fin = fopen("fact.in", "r");
  FILE* fout = fopen("fact.out", "w");

  uint64_t p;
  fscanf(fin, "%"PRIu64, &p);

  fprintf(fout, "%"PRIu64"\n", cauta(p, 1, UINT32_MAX >> 10));
}