1. 程式人生 > >每日一題之 經典面試題 N!末尾有多少個0

每日一題之 經典面試題 N!末尾有多少個0

問題:N的階乘(N!)中的末尾有多少個0? 例如: N = 5,N! = 120.末尾有1個0. N = 10,N! = 3628800.末尾有2個0。

分析:看到這個問題,有人可能第一反應是先求出N!,然後再根據求出的結果,最後得出N!的末尾有多少個0。但是轉念一想,會不會溢位。

其實,從”哪些數相乘可以得到10”這個角度,問題就變得比較的簡單了。 首先考慮,如果N的階乘為K和10的M次方的乘積,那麼N!末尾就有M個0。 N的階乘可以分解為: 2的X次方,3的Y次方,5的次Z方…..的一系列質因子相乘。由於10 = 2 * 5,所以M只能和X和Z有關,每一對2和5相乘就可以得到一個10,於是M = MIN(X,Z),因為是階乘,所以2的次方X大於5的次方Z,因為被2整除的頻率比被5整除的頻率高的多。所以可以把公式簡化為M=Z.

由上面的分析可以看出,只要計算出Z的值,就可以得到N!末尾0的個數

方法一 要計算Z,最直接的方法就是求出N的階乘的所有因式(1,2,3,…,N)分解中5的指數。然後求和

int fun1(int n)
{
    int num = 0;
    int i,j;

    for (i = 5;i <= n;i += 5)
    {
        j = i;
        while (j % 5 == 0)
        {
            num++;
            j /= 5;
        }
    }

    return num;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

方法二:

Z = N/5 + N /(5*5) + N/(5*5*5)…..直到N/(5的K次方)等於0

公式中 N/5表示不大於N的數中能被5整除的數貢獻一個5,N/(5*5)表示不大於N的數中能被25整除的數再貢獻一個5…….

int fun2(int n)
{
    int num = 0;

    while(n)
    {
        num += n / 5;
        n = n / 5;
    }

    return num;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12