Preguntas de la entrevista escrita: 1000 pregunta factorial

      Publicado originalmente en:

 

 

      El problema factorial de los números grandes es muy común. Mira las preguntas de la entrevista de la empresa T:

      Pregunta uno:

      ¿Cuántos ceros hay al final del factorial de 1000?

      Pregunta dos:

      ¿Cuántos dígitos tiene el factorial de 1000?

      Pregunta tres:

      ¿Cuál es el valor del factorial de 1000?

 

 

¿Cuántos ceros hay al final del factorial de 1000?

     ¿Cálculo recursivo directamente? Es un poco ingenuo. El factorial de 1000 es un número muy grande y tenemos que buscar otras formas. Nota: Lo que se requiere es el número de ceros al final del factorial de 1000, no el factorial de 1000.     

     Obviamente, a partir del proceso de descomposición de los factores primos, la terminación 0 debe ser el producto de 2 y 5, y en el factorial, 5 es el valor de escasez y 2 es la plusvalía, por lo que solo es necesario conocer el 5 de la factores primos. Solo cuenta. Tomemos como ejemplo el factorial de 26:

26!
= 1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * ... * 25 * 26
= 1 * 2 * 3 * 2*2 * 5 * 2*3 * 7 * 2*2*2 * 9 * 2*5 * 11 * ...3*5 * ... * 4*5 * ... * 5*5 * 2*13

     Se puede ver que hay 6 5 y hay suficientes 2, por lo que solo se necesita el número de 5. Es fácil saber que hay 6 ceros al final del factorial de 26. Mirándolo con la calculadora factorial, realmente se ve así:

     

     Analicemos la situación más general:

     Sea f (x) el número del factor 5 en x, y [x] es el valor de x redondeado hacia abajo, entonces:

f(n!)
= f(1 * 2 * 3 * 4 * 5 * 6 * ... * n)
= f(1 * 2 * 3 * 4 * 5 * 6 * ... * ([n/5]*5))
= f(5 * 10 * ... * ([n/5]*5))
= f(5*1 * 5*2 * ... * ([n/5]*5))
= f(5^[n/5] * 1 * 2 * ... * [n/5])
= [n/5] + f(1 * 2 * ... * [n/5])
= [n/5] + [n/25] + f(1 * 2 * ... * [n/25])
= [n/5] + [n/25] + [n/125] + f(1 * 2 * ... * [n/125])
= [n/5] + [n/25] + [n/125] + [n/625] + ... + 0

      y entonces:

f(1000!) 
= [1000/5] + [1000/25] + [1000/125] + [1000/625] + [1000/3125]
= 200 + 40 + 8 + 1 + 0
= 249

       En cuanto al programa, da una versión recursiva:

package main

import (
    "fmt"
)

func getNum(i int) int {
    if i < 5 {
        return 0
    }
    
    return i/5 + getNum(i/5)
}

func main() {
    fmt.Println(getNum(1000))
}

      Resultado: 249. Se puede ver que hay 249 ceros al final del factorial de 1000.

 

 

¿Cuántos dígitos tiene el factorial de 1000?

      ¿Cálculo recursivo directamente? Es un poco ingenuo. Veamos las siguientes reglas:

lg99 = 1.a
lg100 = 2
lg101 = 2.b

lg999 = 2.c
lg1000 = 3
lg1001 = 3.d

      Sea f (x) el número de dígitos de x y [x] el valor de x redondeado hacia abajo, entonces:

f(x)
= [lg(x)] + 1

f(n!)
= f(1 * 2 * 3 * ... * n)
= [lg(1 * 2 * 3 * ... * n)] + 1
= [lg1 + lg2 + lg3 + ... + lg(n)] + 1

       En cuanto al procedimiento, es muy sencillo:

package main

import (
    "fmt"
    "math"
)

func main() {
    f := float64(0)
    for i := 1; i <= 1000; i++ {
       f = f + math.Log10(float64(i))
    }
    
    n := int(f) + 1
    fmt.Println(n)
}

      Resultado: 2568. Se puede ver que el factorial de 1000 tiene 2568 bits.

 

 

¿Cuál es el valor del factorial de 1000?

     ¿Cálculo recursivo directamente? Es un poco ingenuo. Hagámoslo con cadenas:

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
 
int multi(char a, char b)
{
  return (a - '0') * (b - '0');
}
 
void strMulti(char *a, char *b, char *c)
{
  int lenA = strlen(a);
  int lenB = strlen(b);
  int maxLen = lenA + lenB;
  int *p = new int[maxLen];
  memset(p, 0, maxLen * sizeof(int)); 
  
  int i = 0;
  int j = 0;
  for(j = lenB - 1; j >= 0; j--)
  {
    for(i = lenA - 1; i >= 0; i--)
    {
      p[j + i + 1] += multi(b[j], a[i]);
    }
  }
 
  // 处理进位操作
  for(i = maxLen - 1; i >= 1; i--)
  {
    p[i - 1] += p[i] / 10;
    p[i] = p[i] % 10;
  }
 
  int *s = p;
 
  // m位正整数和n位正整数相乘,结果的位数必然是(m+n-1)位或者(m+n)位
  if(0 == p[0])
  {
    p++;
  }
  
  int *pTmp = NULL;
  for(pTmp = p; pTmp < s + maxLen; pTmp++)
  {
    *c++ = *pTmp + '0';
  }
 
  *c = '\0';
  delete s;
}
 
void factorial(int n, char *str)
{
  int i = 0;
  *str = '1';
  *(str + 1) = '\0';
  char b[5000] = {0};
  for(i = 1; i <= n; i++)
  {
    snprintf(b, sizeof(b), "%d", i);
    strMulti(str, b, str);
  }
}
 
int main()
{
  char str[5000] = {0};
  factorial(1000, str); 
  cout << str << endl << endl;
  return 0;
}

      El resultado es:

     Como puede ver, el factorial de 1000 tiene 2568 bits y hay 249 ceros al final.

 

 

     Eso es todo sobre el factorial de 1000. Al encontrarnos con problemas, debemos ser flexibles, de lo concreto a lo abstracto, y captar la esencia.

Supongo que te gusta

Origin blog.csdn.net/stpeace/article/details/108921577
Recomendado
Clasificación