階乘相關問題

2021-09-08 11:10:15 字數 2049 閱讀 3334

定義:

乙個正整數的階乘(英語:factorial)是所有小於及等於該數的正整數的積,並且有0的階乘為1。自然數n的階乘寫作n!。

亦即n!=1×2×3×...×n。階乘亦可以遞迴方式定義:0!=1,n!=(n-1)!×n。

問題1、給定乙個整數n,那麼n的階乘n!末尾有多少個0呢?例如:n = 10 , n! = 3628800,n!的末尾有兩個0。

解析:加入完整得計算n!的階乘,很可能發生溢位。我們可以從另外的角度出發,「哪些數相乘能的到10」。

n! = k * 10的m次方,k不能被10整除,那麼n!末尾就有m個0.對n!進行質因數分解,n!=2的x次方 × 3的y次方 × 5的z次方 ×…… ,由於10=2×5,所以m只跟x和z有關,每一對2和5相乘可以得到乙個10,於是m = min(x,z)。不難看出x大於等於z,因為能被2整除的書出現的頻率比被5整除的數高得多,所以吧公式化簡為m = z(能整除的5的個數);

方法1:

最直接的方法,計算i(1,2,3,……,n)的因式分解中5的指數,然後求和。

/**

* 計算n的階乘結果末尾0的位數

* @param

n 求階乘的數

* @return

n的階乘結果末尾0的位數

*/public

static

int getlowzeronum(intn)

} return

ret;

}

方法2:公式法

(不用擔心這回事乙個無窮的運算,因為總存在乙個k,使得 5的k次方 > n,【n/5的k次方】 = 0。

公式中,【n/5】表示不大於n的數中5的倍數貢獻乙個5,【n/5的平方】表示不大於n的數中,5的平凡的倍數在貢獻乙個5…… **如下:

/**

* 計算n的階乘結果末尾0的位數

* @param

n 求階乘的數

* @return

n的階乘結果末尾0的位數

*/public

static

int getlowzeronum2(intn)

return

ret;

}

問題2、求n!的二進位制表示中最低位1的位置

把乙個2進製數除以2,判斷最後乙個二進位制位是否為0;若為0,則將此二進位制數右移一位,即為商值;反之,若為1,則說明這個二進位制數是奇數,無法被2整除。所以這個問題實際上等同於求n!含有質因數2的個數。即答案等於n!含有質因數2的個數加1

解法1:

n!中含有質因數2的個數,等於【n/2】+【n/4】+【n/8】+【n/16】+ ……,

具體演算法如下:

/**

* n的階乘最低位1的位置

* @param

n 求階乘的數

* @return

n的階乘最低位1的位置

*/public

static

int gettheposition(intn)

return

ret;

}

測試:

public

static

void

main(string args)

結果:

5的階乘結果末尾0的位數:1

5的階乘結果末尾0的位數:1

5n的階乘最低位1的位置:3

小結:

任意乙個長度為m的二進位制數n可以表示為 n = b[1] +

大數階乘問題

由於大數的階乘已經超過整型所能夠表示的最大值,屬於大數操作問題,需要採用字串進行操作。本文對n進行階乘求取,分解為兩個函式 void multiply char s1,char s2,char out 計算兩個字串的乘積,結果存入字串void calcnn int n,char pout 計算n的階...

問題 A 階乘分解

題目描述 給定整數n 1 n 10 6 試把階乘n 分解質因數,按照算術基本定理的形式輸出分解結果中的pi和ci即可。輸入乙個整數n。輸出n 分解質因數後的結果,共若干行,每行一對pi,ci,表示含有pi ci項。按照pi從小到大的順序輸出。樣例輸入 複製樣例資料 5樣例輸出 2 33 1 5 1提...

sdut2500 0 s 階乘相關

求階乘末尾零個數的方法,剛學會的 具體參見 include include include define ll long long using namespace std ll a ll f ll t int main return 0 problem id sdut oj 2500 result ...