求一个数阶乘末尾0的个数

#include<iostream>
using namespace std;
//给定一个整数N,那么N的阶乘末尾有几个0?N=10,N!=3628800,末尾有2个0
//1.如果我们从“哪些数相乘能得到 10”这个角度来考虑,问题就变得简单了。
//首先考虑,如果 N!= K×10M,且 K 不能被 10 整除,那么 N!末尾有 M 个 0。再考虑
//对 N!进行质因数分解,N!=(2x)×(3y)×(5z)…,由于 10 = 2×5,所以 M 只跟 X 和 Z
//相关,每一对 2 和 5 相乘可以得到一个 10,于是 M = min(X, Z)。不难看出 X 大于等于 Z,
//因为能被 2 整除的数出现的频率比能被 5 整除的数高得多,所以把公式简化为 M = Z。
//根据上面的分析,只要计算出 Z 的值,就可以得到 N!末尾 0 的个数。 
//最直接的方法,就是计算 i(i =1, 2, …, N)的因式分解中 5 的指数,然后求和
int count1(int n)
{
	int ret=0;
	int j=0;
	for(int i=1;i<=n;++i)
	{
		j=i;
		while(j%5==0)
		{
			++ret;
			j/=5;
		}
	}
	return ret;
}
//2.公式:Z = [N/5] +[N/52] +[N/53] + …(不用担心这会是一个无穷的运算,因为总存在一
//个 K,使得 5K > N,[N/5K]=0。)
//公式中,[N/5]表示不大于 N 的数中 5 的倍数贡献一个 5,[N/52]表示不大于 N 的数中 52
//的倍数再贡献一个 5
int count2(int n)
{
	int ret=0;
	while(n)
	{
		ret+=n/5;
		n/=5;
	}
	return ret;
}
int main()
{
	cout<<count1(10)<<endl;
	cout<<count2(10)<<endl;
	return 0;
}
#include<iostream>
using namespace std;
//求N!的二进制表示中最低位1的位置给定一个整数 N,求 N!二进制表
//示的最低位 1 在第几位?例如:给定 N = 3,N!= 6,那么 N!的二进制表示(1 010)的最低
//位 1 在第二位。 

//思路:判断最后一个二进制位是否为 0,若为 0,则将此二进制数右移一位,即为商值(为什
//么);反之,若为 1,则说明这个二进制数是奇数,无法被 2 整除(这又是为什么)。
//所以,这个问题实际上等同于求 N!含有质因数 2 的个数。即答案等于 N!含有质因数
//2 的个数加 1 
//由于 N! 中含有质因数 2 的个数,等于 N/2 + N/4 + N/8 + N/16 + …1,
int lowestOne(int N)
{
	int Ret = 1;//+最后的1 
	while(N)
	{
		N >>= 1;
		Ret += N;
	}
	return Ret;
}
//N!含有质因数 2 的个数,还等于 N 减去 N 的二进制表示中 1 的数目。我们还可以通过
//这个规律来求解。
 int count3(int v)
 {
 	int num=0;
 	while(v)
 	{
 		v&=(v-1);
 		++num;
	}
	 return num;
} 
int lowestOneCount(int N)
{
	return N-count3(N)+1;
}
int main()
{
	cout<<lowestOne(3)<<endl;
	cout<<lowestOneCount(3)<<endl;
	return 0;
}
时间: 2024-10-12 23:11:16

求一个数阶乘末尾0的个数的相关文章

阶乘末尾0的个数(证明)

先给出算法: 给定n,求n的阶乘末尾0的个数. int res = 0; while (n > 0) { res += n / 5; n /= 5; } 因为: 比方说求15的阶乘,也就是求 1 × 2 × 3 × 4 × 5 × 6 × 7 × 8 × 9 × 10 × 11 × 12 × 13 × 14 × 15 的末尾0的个数.现在我们把这15个数分解出来含有5的因子 1 × 2 × 3 × 4 × 5 × 6 × 7 × 8 × 9 × 2   × 11 × 12 × 13 × 14 ×

N的阶乘末尾0的个数和其二进制表示中最后位1的位置

问题一解法: 我们知道求N的阶乘结果末尾0的个数也就是说我们在从1做到N的乘法的时候里面产生了多少个10, 我们可以这样分解,也就是将从0到N的数分解成因式,再将这些因式相乘,那么里面有多少个10呢? 其实我们只要算里面有多少个5就可以了? 因为在这些分解后的因子中,能产生10的可只有5和2相乘了,由于2的个数是大于5的个数的,因此 我们只要算5的个数就可以了.那么这个题目就是算这些从1到N的数字分解成因子后,这些因子里面 5的个数. Python代码 def factorialnumberof

Java 计算N阶乘末尾0的个数-LeetCode 172 Factorial Trailing Zeroes

题目 Given an integer n, return the number of trailing zeroes in n!. Note: Your solution should be in logarithmic time complexity. 分析 Note中提示让用对数的时间复杂度求解,那么如果粗暴的算出N的阶乘然后看末尾0的个数是不可能的. 所以仔细分析,N! = 1 * 2 * 3 * ... * N 而末尾0的个数只与这些乘数中5和2的个数有关,因为每出现一对5和2就会产生

LightOj 1138 - Trailing Zeroes (III) 阶乘末尾0的个数 &amp; 二分

题目链接:http://lightoj.com/volume_showproblem.php?problem=1138 题意:给你一个数n,然后找个一个最小的数x,使得x!的末尾有n个0:如果没有输出impossible 可以用二分求结果,重点是求一个数的阶乘中末尾含有0的个数,一定和因子5和2的个数有关,因子为2的明显比5多,所以我们只需要求一个数的阶乘的因子中一共有多少个5即可; LL Find(LL x) { LL ans = 0; while(x) { ans += x/5; x /=

阶乘末尾0的个数

问题很简单:给定一个整数n,那么n的阶乘末尾有多少个连续的0呢? 那个可以去求这个阶乘吗,大数的代码上去一套?这个大数求出来肯定是很慢的,还有其他方法吗,你可以观察一个产生0,本质是2*5,出现了2一定会出现5,2的个数会大于5的个数,所以我可以直接统计5的个数,统计每个数有几个因子5 #include <bits/stdc++.h> using namespace std; int main() { int n; while (cin >> n) { int num = 0 ,i

阶乘末尾0的个数问题

问题:给定一个整数N,那么N的阶乘N!末尾有多少个0? 比如:N=10,N!=3628800,N!的末尾有2个0,写出算法. 回答: int countZero(int N) {    int ans = 0;    int maxInt = 1000000000;//10^9    int  tmpn = N;    while(tmpn){        maxInt /= 10;        tmpn /= 10;    }    int lastBit = 1; //保存上一个阶乘 的

p74 阶乘末尾0的个数(leetcode 172)

一:解题思路 Time:O(log_5(n)),Space:O(1) 二:完整代码示例 (C++版和Java版) C++: class Solution { public: int trailingZeroes(int n) { int count = 0; while (n > 0) { n /= 5; count += n; } return count; } }; Java: class Solution { public int trailingZeroes(int n) { int c

[LeetCode] Factorial Trailing Zeroes 求阶乘末尾零的个数

Given an integer n, return the number of trailing zeroes in n!. Note: Your solution should be in logarithmic time complexity. Credits:Special thanks to @ts for adding this problem and creating all test cases. 这道题并没有什么难度,是让求一个数的阶乘末尾0的个数,也就是要找乘数中10的个数,

求N的阶乘N!中末尾0的个数

有道问题是这样的:给定一个正整数N,那么N的阶乘N!末尾中有多少个0呢?例如:N=10,N!=3628800,则N!的末尾有两个0: 直接上干货,算法思想如下: 对于任意一个正整数N!,都可以化为N!= (2^X)  * (3^Y)* (5^Z)......的形式,要求得末尾0的个数只需求得min(X, Z)即可, 由于是求N!,则X >= Z; 即公约数5出现的频率小于等于2出现的频率,即Z=min(X, Z),即出现0的个数等于公约数5出现的次数: 源码如下: 方法一: #include <