1. 给定一个整数N,那么N的阶乘N!末尾有多少个0?
2. 求N!的二进制表示中最低位1的位置
*************************************************************/
/************************问题1思路****************************
N!=K*power(10,M),K不能被10整除,则N!末尾有M个0。对N!进行质因数
分解,有N!=power(2,X)*power(3,Y)*power(5,Z)*...,由于10=2×5,
因此N!有多少个0显然只与X,Z有关,易得M=min(X,Z),因为2出现的频率
大于等于5,所以M=Z,即问题化简为求N!中5的个数
*************************************************************/
/***********************解法1:直接暴力**********************
遍历i=1,2,...,N中每个因子包含5的个数,然后相加
************************************************************/
int findNumof5v1(int N){
int count=0;
for(int i=1;i<=N;i++){
int j=i;
while(j%5==0){
count++;
j/=5;
}
}
return count;
}
/**********************解法2:*****************************
Z=小于N的数中是5的倍数的个数+25的倍数的个数+125的倍数的个数...
即Z=[N/5]+[N/(5*5)]+[N/(5*5*5)]+...
***********************************************************/
int findNumof5v2(int N){
int count=0;
while(N){
count += N/5 ;
N /=5 ;
}
return count;
}
/*************************问题2思路***************************
跟问题1类似,可以先求出N!中2的个数(因为每存在一个2,则在数的
最低位多1个0)。因此求1的最低位的位置即为N!中2的个数+1;
*************************************************************/
int lowestOnePos(int N){
int count=0;
while(N){
count += N/2 ;
N /= 2;
}
return count + 1 ;
}
求一个数的二进制表示中1的个数
/**************问题描述************
求二进制数中1的个数
**********************************/
#include<iostream>
using namespace std;
/****************解法一:直接除2*******************
对num除以2,余数为1则result加1,时间复杂度为O(logv)
v为num的二进制位数
**************************************************/
int Count1(int num){
int result=0;
while(num){
if(num %2 ==1){
result++;
}
num /=2;
}
return result;
}
/******************解法二:使用位操作*************
对num使用位运算,将num与0x01做位与,为1则result加1
时间复杂度为O(logv),v为num的二进制位数
*************************************************/
int Count2(int num){
int result=0;
while(num){
result += num&1 ;
num >>= 1;
}
return result;
}
/***************解法三:光考虑1的个数************
例如对num=15=1111,
num=num&(num-1)=1111&1110=1110,result=1;
num=num&(num-1)=1110&1101=1100,result=2;
num=num&(num-1)=1100&1011=1000,result=3;
num=num&(num-1)=1000&0111=0000,result=4;
时间复杂度O(M),M为num的位数
*************************************************/
int Count3(int num){
int result=0;
while(num){
num &= (num-1);
result ++;
}
return result;
}
/***************解法四:时空折中*****************
假设知道输入的num为几位数的话,可以预先存好每个数
有多少个1,然后到时候直接查询即可。这样需要多申请
2^n那么大的数组来保存,但是时间复杂度为O(1)
*************************************************/
#define MAIN
#ifdef MAIN
int main(){
int num=16;
int result=Count1(num);
cout<<"Result1: "<<result<<endl;
cout<<"Result2: "<<Count2(num)<<endl;
cout<<"Result3: "<<Count3(num)<<endl;
system("PAUSE");
return 0;
}
#endif