思路一:
計算出n!= nValue,然后 nValue % 10 == 0 則nCount自增1,nValue /= 10 直到條件為否,最后nCount就是我們想要的結果,代碼如下:
1 int CountZero(int n) 2 { 3 unsign long long nValue = 1; 4 for (int i = 2; i <= n; i ++) 5 { 6 nValue *=i; 7 } 8 int nCount = 0; 9 while(0 == nValue % 10) 10 { 11 nCount ++; 12 nValue /= 10; 13 } 14 return nCount; 15 }
代碼簡潔易懂,看上去還不賴,但是這里要考慮一個問題就是在求n!整數溢出了怎么辦? 顯然我們使用_int64也同樣會有溢出的時候,所以上面的代碼實際上是不可行的。
思路二:
不知道怎么辦,不妨先舉例分析:
1! = 1 2! = 1 * 2 = 2 3! = 1 * 2 *3 = 6 4! = 1 * 2 * 3 * 4 = 24 5! = 1 * 2 * 3 * 4 * 5 = 120 ........ 1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14 * 15 * 16 * 17 * 18 * 19 * 20 * 21 * 22 *23 * 24 * 25
我們會發現一個因子2和因子5組合產生一個0,這樣我們只需統計1到n有多少個因子對,即n!的尾隨零個數,因子2的個數比因子5的個數多,因此我們只需統計出因子5的個數即可,如
5,10,15,25,30,35,40.......
需要注意的是,以100!為例:
統計一次5的倍數 (5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100)= 20
統計一次25的倍數(因為25的倍數有兩個5的因子,所以再統計一次)(25,50,75,100) = 4
統計一次125的倍數(125的倍數由3個5的因子,所以再統計一次,以此類推)(nil)
所以100!的尾隨零個數為24個
實現代碼如下:
1 int CountZero(int n) 2 { 3 int count = 0; 4 if (n < 0) 5 return -1; 6 for (int i = 5; n / i > 0; i *= 5) 7 count += n / i; 8 return count; 9 }
運行結果:
1 1 0 0 2 2 0 0 3 6 0 0 4 24 0 0 5 120 1 1 6 720 1 1 7 5040 1 1 8 40320 1 1 9 362880 1 1 10 3628800 2 2 11 39916800 2 2 12 479001600 2 2 13 6227020800 2 2 14 87178291200 2 2 15 1307674368000 3 3 16 20922789888000 3 3 17 355687428096000 3 3 18 6402373705728000 3 3 19 121645100408832000 3 3 20 2432902008176640000 4 4 21 14197454024290336768 0 4 22 17196083355034583040 1 4 23 8128291617894825984 0 4 24 10611558092380307456 0 4
當n=21時,21!已經溢出。