《编程之美》第2.2节:不要被阶乘吓倒
问题一:给定一个整数N,那么N的阶乘N!末尾有多少个0?
方法一:遍历1-N所有数,求出N!的因式分解时5的个数即可。
方法二:求5的个数时,有N/5+N/5^2+N/5^3+……,表示N能够分解成几个5这个因子,因为N/k表时N中有几个数能够被k整除,这样N/5表示N中能被5整除的数,然后N/25表示N中能被25整除的数,此时本应该加两次,但是前面能被5整除的数已经加了一次,因此这里只需要再加一次即可,依次类推,可以得到方法二的解法代码。
#include<iostream>
using namespace std;
//求N!中0的个数
int calculatZerosNum1(int N)
{
int result=0;
for(int i=1;i<=N;i++)
{
int temp=i;
while(temp%5==0)
{
result++;
temp/=5;
}
}
return result;
}
//求N!中0的个数=N!因数分解后5的个数
//同时等于N/5+N/5^2+N/5^3+……
int calculatZerosNum2(int N)
{
int result=0;
while(N)
{
result+=N/5;
N/=5;
}
return result;
}
int main()
{
const int N=1000;
cout<<calculatZerosNum1(N)<<endl;
cout<<calculatZerosNum2(N)<<endl;
system("pause");
return 0;
}
问题二:求N!的二进制表示中最低位1的位置
方法1、最低位1的位置,表示这个1最后都是0,即用二进制表示末尾有几个0,十进制末尾的一个0表示能被10整除,那么二进制表示的一个0就是能被2整除,即N!中因数分解后2的个数。而问题1求的是5的个数,类似的程序。
方法2、N-(N中1的个数)
#include<iostream>
using namespace std;
//求N!中二进制表示最低位1的位置
int lowestOne1(int N)
{
int result=0;
while(N)
{
N>>=1;
result+=N;
}
return result;
}
int lowestOne2(int N)
{
int result=0;
int temp=N;
while(temp)
{
result++;
temp&=temp-1;
}
return N-result;
}
int main()
{
const int N=5;
cout<<lowestOne1(N)<<endl;
cout<<lowestOne2(N)<<endl;
system("pause");
return 0;
}
相关问题:给定整数N,判断它是否是2的幂次
解法:如果N==0或者N中1的个数只有一个,那么肯定是2的幂次
#include<iostream>
using namespace std;
//给定N判断是否是2的幂次
//条件:N!=0且N中只有一个1
bool ifPowOfTow(int N)
{
return (N!=0) && !(N&(N-1));
}
int main()
{
const int N=64;
cout<<ifPowOfTow(N)<<endl;
system("pause");
return 0;
}