N!末尾有多少个0
给定一个整数N,那么N的阶乘N!末尾有多少个0呢?例如:N=10,N!=3 628 800,N!的末尾有两个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
【解法一:分析后①】 #include<iostream> using namespace std; int main() { int n; int num,p; n = 0; cin>>num; for(int i=1; i<=num; i++) { p = i; while(p % 5 == 0) { p/= 5; n++; } } cout<<n<<endl; return 0; } 【解法二:分析后②】 //公式:Z = [N/5] +[N/5^2] +[N/5^3] + …(总存在一个K,使得5^K > N,[N/5^K]=0) //公式中,[N/5]表示不大于N的数中5的倍数贡献一个5,而[N/5^2]表示不大于N的数中5^2的倍数再贡献一个5 #include<iostream> using namespace std; int main() { int n; int num, tmp; n = 0; cin>>num; while(num) { n += num/5; num /= 5; } cout<<n<<endl; return 0; } 【解法三:储存一定数】 # include<iostream> using namespace std; int main() { int nNum,sum,i,loop; while(cin>>nNum) { sum=1; loop=0; for(i=nNum;i>=1;i--) { sum*=i; while(sum%10==0)//消0 { sum/=10; loop++; } if(sum>=100000)//保存末尾5位数字即可 sum%=100000; } while(sum%10==0)//消0 { sum/=10; loop++; } cout<<loop<<endl; } return 0; } //这种解法后面解“从最末一个非0位开始自低位向高位数的第1或K位”还有用,同理
浙公网安备 33010602011771号