計算階乘n!末尾0的個數


一、問題描述

  給定一個正整數n,請計算n的階乘n!末尾所含有“0”的個數。例如:

  • 5!=120,其末尾所含有的“0”的個數為1;
  • 10!= 3628800,其末尾所含有的“0”的個數為2;
  • 20!= 2432902008176640000,其末尾所含有的“0”的個數為4。

二、算法分析

  此類問題很顯然屬於數學問題,一定要找到其中的本質規律才能得到正確的數學模型。

  兩個大數字相乘,都可以拆分成多個質數相乘,而質數相乘結果尾數為0的,只可能是2*5。如果想到了這一點,那么就可以進一步想到:兩個數相乘尾數0的個數其實就是依賴於2和5因子的個數。又因為每兩個連續數字就會有一個因子2,個數非常充足,所以此時只需要關心5因子的個數就行了。

  對於一個正整數n來說,怎么計算n!中5因子的個數呢?我們可以把5的倍數都挑出來,即:

  令n! = (5*K) * (5*(K-1)) * (5*(K-2)) * ... * 5 * A,其中A就是不含5因子的數相乘結果,n = 5*K + r(0<= r <= 4)。假設f(n!)是計算階乘n!尾數0的個數,而g(n!)是計算n!中5因子的個數,那么就會有如下公式:

  f(n!) = g(n!) = g(5^K * K! * A) = K + g(K!) = K + f(K!),其中K=n / 5(取整數)。

  很顯然,當0 <= n <= 4時,f(n!)=0。結合這兩個公式,就搞定了這個問題了。舉幾個例子來說:

  • f(5!) = 1 + f(1!) = 1
  • f(10!) = 2 + f(2!) = 2
  • f(20!) = 4 + f(4!) = 4
  • f(100!) = 20 + f(20!) = 20 + 4 + f(4!) = 24
  • f(1000!) = 200 + f(200!) = 200 + 40 + f(40!) = 240 + 8 + f(8!) = 248 + 1 + f(1) =249

三、代碼實現

   使用遞歸函數來做,非常的簡單,直接套用公式即可:

#include <iostream>
using namespace std;

int GetN_1(int n)
{
    if (n < 5)
    {
        return 0;
    }
    else
    {
        return (n / 5 + GetN_1(n / 5));
    }
}

int main()
{
    cout << GetN_1(1000) << endl;  // 輸出249

    system("pause");
    return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM