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位”还有用,同理

 

 

 

posted on 2012-05-09 09:30  即为将军  阅读(2358)  评论(0)    收藏  举报

导航