滴滴2017校園招聘程式設計題——階乘末尾0的個數
阿新 • • 發佈:2019-02-02
1、題目如下圖所示:
2、分析:
這個題目描述的很簡單,思路看似也很清晰,我們第一想到的肯定就是正常計算和統計——先計算N!階乘的結果,然後統計結果末尾0的個數。看似這是一個很好的也很簡單的理想方案,這裡我們也先不管合不合理,先看看它的實現過程,程式碼貼出如下:
#include<iostream> using namespace std; /*****計算N!的值****/ int fac(int nNum) { if(nNum<0) return 0; if(nNum==0 || nNum==1) return 1; return nNum*fac(nNum-1); } int main() { int nNum,nRel=0; cin>>nNum; long nSum = fac(nNum); while( !(nSum %10)) //計算階乘末尾0的個數 { nRel++; nSum /= 10; } cout<<nRel<<endl; return 0; }
當你把程式執行後會發現,明明一些尾數肯定存在0的數,例如15!,但是計算結果卻統計沒有。那麼問題出在了哪裡呢?
這裡我們聯想一下初中時候一個經典問題,即2的次方引發的恐慌。當計算2的64次方時候,看似沒有多少步,但是實際上結果確是一個天文數字。同樣的道理,因為階乘的計算的遞增速度是很高的,且long型別在32位編譯器上僅分配4個位元組記憶體,而64位上也就8個位元組。在32位編輯器上,實際上算到13!就已經超出了它最大的儲存範圍。而題目要求最大可以取到1000,所以這個題並不能以簡單計算統計的方式解決,還是要從資料規律上考慮。
我們可以看乘數的規律,資料末尾能出現0的可能性最簡單形式是2*5。例如:5!=1*2*3*(2*2)*5,出現了一個2*5,所以末尾有1個零。由於每個資料在分解的時候,會出現2的個數比5多的多,所以匹配的話,只要統計資料集分解後5的個數即可。例如:15!中15之前能統計出3個5,即結果末尾存在3個0。
程式碼如下:
#include<iostream> using namespace std; int main(void) { int nNum,nSum=0; int nMid =5; cin>>nNum; while(nNum>=nMid) //統計nNum!前能分解出5的個數,注意25能分解出兩個 { nSum += (nNum / nMid); nMid*=5; } cout<<nSum<<endl; return 0; }
轉載請註明出處:CSDN 無鞋童鞋。