N!的末尾有几个零以及二进制表示最右边1的位置

给定一个整数N,求解整数N!末尾0的个数 问题描述 1、给定一个整数N,阶乘N!末尾有多少个0 2、求N!的二进制表示中最低位1的位置 1、给定一个整数N,阶乘N!末尾有多少个0 举例:10!=3 628 800,则 N!的末尾有两个0 思路:   即,知道 Z ,就知道N!中含有0的个数 方法一:求出1~N中每一个数被5整除的因子的个数,比较笨 代码: [cpp 阅读详情

问题一:求n!后面有多少个0。

        N的阶乘可以分解为: 2的X次方,3的Y次方,4的5次Z方,.....的成绩。由于10 = 2 * 5,所以M只能和X和Z有关,每一对2和5相乘就可以得到一个10,于是M = MIN(X,Z),不难看出X大于Z,因为被2整除的频率比被5整除的频率高的多。所以可以把公式简化为M=Z.
 由上面的分析可以看出,只要计算处Z的值,就可以得到N!末尾0的个数。
令f(x)表示正整数x末尾所含有的“0”的个数,则有:
      当0 < n < 5时,f(n!) = 0;
      当n >= 5时,f(n!) = k + f(k!), 其中 k = n / 5(取整)。

 显然,对于阶乘这个大数,我们不可能将其结果计算出来,再统计其末尾所含有的“0”的个数。所以必须从其数字特征进行分析。下面我们从因式分解的角度切入分析。

    我们先考虑一般的情形。对于任意一个正整数,若对其进行因式分解,那么其末尾的“0”必可以分解为2*5。在这里,每一个“0”必然和一个因子“5”相对应。但请注意,一个数的因式分解中因子“5”不一定对应着一个“0”,因为还需要一个因子“2”,才能实现其一一对应。

    我们再回到原先的问题。这里先给出一个结论:
    结论1: 对于n的阶乘n!,其因式分解中,如果存在一个因子“5”,那么它必然对应着n!末尾的一个“0”。
    下面对这个结论进行证明:
    (1)当n < 5时, 结论显然成立。
    (2)当n >= 5时,令n!= [5k * 5(k-1) * ... * 10 * 5] * a,其中 n = 5k + r (0 <= r <= 4),a是一个不含因子“5”的整数。
    对于序列5k, 5(k-1), ..., 10, 5中每一个数5i(1 <= i <= k),都含有因子“5”,并且在区间(5(i-1),5i)(1 <= i <= k)内存在偶数,也就是说,a中存在一个因子“2”与5i相对应。即,这里的k个因子“5”与n!末尾的k个“0”一一对应。
    我们进一步把n!表示为:n!= 5^k * k! * a(公式1),其中5^k表示5的k次方。很容易利用(1)和迭代法,得出结论1。
    
    上面证明了n的阶乘n!末尾的“0”与n!的因式分解中的因子“5”是一一对应的。也就是说,计算n的阶乘n!末尾的“0”的个数,可以转换为计算其因式分解中“5”的个数。

    令f(x)表示正整数x末尾所含有的“0”的个数, g(x)表示正整数x的因式分解中因子“5”的个数,则利用上面的的结论1和公式1有:
       f(n!) = g(n!) = g(5^k * k! * a) = k + g(k!) = k + f(k!)
所以,最终的计算公式为:
    当0 < n < 5时,f(n!) = 0;
    当n >= 5时,f(n!) = k + f(k!), 其中 k = n / 5(取整)。

代码如下:

int LowestZeros2(int N)
{
	int ret = 0;
	while (N)
	{
		ret += N /5;
		N /= 5;
	}
	return ret;
}
原始的求5的指数代码:

int LowestZeros(int N)
{
	int ret = 0;
	for(int i = 1;i <= N; i++)
	{
		int j = i;
		while(j % 5 == 0)
		{
			ret++;
			j /= 5;
		}
	}
	return ret;
}
问题二:求N!的二进制表示中最低位1的位置。

同上即为求N!中质因数2的个数,利用与上相同的思路,可以得到如下代码:

int LowestOne(int N)
{
	int  ret = 0;
	while(N)
	{
		N >>= 1;
		ret += N; 
	} 
	return ret;
}
测试:

int main()
{
	printf("%d\n",factorial(9));
	printf("%d\n",LowestZeros(25));
	printf("%d\n",LowestZeros2(25));
	printf("%d\n",LowestOne(25));
	getchar();	
}
结果:

362880
6
6
22
REF:

1,http://blog.youkuaiyun.com/niushuai666/article/details/6695790

2,编程之美







C++返回一个数的二进制最右边的一位的实现算法(附完整源码) C++返回一个数的二进制最右边的一位的实现算法C++返回一个数的二进制最右边的一位的实现算法完整源码(定义,实现,main函数测试) C++返回一个数的二进制最右边的一位的实现算法完整源码(定义,实现,main函数测试) #include <iostream> #include <cmath> int position_of_first_set_bit( int num ) { return log2(num & -num) + 1; } int main() { 阅读详情

相关推荐

COLMAP在Ubuntu下的编译陷阱与实战避坑指南——从环境配置到三维重建全流程

本文详细介绍了在Ubuntu系统下编译和配置COLMAP三维重建工具的全流程,包括环境准备、依赖库安装、CUDA加速配置以及常见编译问题的解决方案。通过实战案例演示了从图像特征提取到稠密重建的完整步骤,并提供了性能优化和问题排查的实用技巧,帮助用户高效完成三维重建任务。

weixin_29003437的博客 1048

算法 | 如何把一个int型二进制数的最右侧的1提取出来?

本文主要介绍如何把一个int型二进制数的最右侧的1提取出来,也就是只保留该int型数对应的二进制最右侧的1,其他的都变为0,并返回对应的10进制数字。现有个数,这个num对应的二进制为,要求把这个数的二进制最右侧的1保留,其他的位置全部变为0,也就是变为,变更后的二进制数对应的十进制为4。从上面两个方案来看,方法二使用位运算比方法一简单的太多了,仅仅简单的一行代码就把功能给实现了,而且在效率方面也远比方法一高的多。

BASK2311的博客 904

Rockchip RK3566 Buildroot SDK构建与内核编译实战指南

嵌入式Linux开发中,交叉编译环境是系统启动的基础支撑。Buildroot作为轻量级嵌入式构建框架,通过配置驱动、自动化下载和分层编译机制,显著降低定制化Linux发行版的集成门槛。其核心价值在于将内核、根文件系统与工具链统一管理,兼顾资源约束下的确定性构建与工程可复现性。典型应用场景涵盖ARM64平台(如RK3566)的固件开发、IoT设备量产镜像生成及硬件Bring-up阶段的快速验证。本文围绕Buildroot SDK全流程实践,深入解析环境搭建、Repo源码同步、离线DL库预置及内核编译等关键环节

weixin_36047538的博客 135

二进制最右侧1及其应用

把一个整型数,提取最右侧的1 int N=0000 1101 1000 1100 变成ans=0000 0000 0000 0100 ans=N&(~N+1) 应用: 一个数组中两种数出现了奇数次,其余的数都出现偶数次,找到并且打印这两种数(最右侧1的应用!) 假设两种数是a和b,则两种数异或的结果为ab,则数组所有数异或的结果为ab。 因为a!=b也就是a^b!=0,所以a和b某一位不相等。假设第8位不同,所以根据第8位为0和1,将数组中所有的数分为两组。 将数组中第八位为1的数和 第八.

weixin_43604021的博客 534

串口调试神器诞生记:我是如何用Cursor+AI自动生成C#上位机的(含VSCode插件清单)

本文详细介绍了如何利用Cursor和AI技术快速开发C#上位机程序,实现高效的串口通讯调试。从开发环境搭建到代码自动生成,再到性能优化和功能增强,全面展示了AI辅助开发在串口调试中的实际应用和显著效率提升。

weixin_28340315的博客 300

极验滑块验证码破解与研究(一):AST还原混淆JS

极验滑块验证码破解与研究(一):AST还原混淆JS声明一、环境安装1. node安装1.1. node下载1.2. 配置环境变量1.3. node安装检测1.4. pycharm配置node环境2. babel库安装2.1. babel库安装命令2.2. babel库安装检测二、AST还原混淆JS1. 模块导入2. AST还原流程3. 复制还原需要用到的js源码4. AST还原函数详解4.1. replace_unicode4.2. replace_unicode, replace_name_array,

帯泪的鱼的博客 1万+

计算机中的二进制

计算机中的二进制简介。

小Y的博客 1541

【AI黑话日日新】什么是AI云原生?

云原生赋能AI:利用容器、微服务、Serverless、DevOps等云原生技术,解决AI应用(尤其是大模型)在部署、扩展、运维、成本控制方面的痛点,让AI服务具备高可用、高性能、易运维、易扩展的特性AI赋能云原生:将AI技术(如智能调度、异常检测、自动优化)融入云基础设施管理,使云平台具备自我感知、自我优化、自我修复的能力,从"被动响应"升级为"主动适配"其本质是实现从""(AI运行在云上)到""(为AI量身打造的云)的根本性转变。

专注:太空算力、AI infra、异构调度、大模型成本工程 627

位运算 二进制数

位运算 二进制数按位异或 “^”按位或 “|”左移运算符 “<<”右移运算符 “>>”实际使用 按位异或 “^” 按位异或运算通常用来将某变量中的某些位取反,且保留其他位不变。 例如,如果需要将int型变量n的低8位取反,而其余位不变,则可以执行: n ^= 0xff; 0xff: 1111 1111 按位或 “|” 按位或运算通常用来将某变量中的某些位置1且保留其他位不变。 例如,如果需要将int型变量n的低8位全置成1,而其余位不变,则可以执行: n |= 0xff; 0xff:

weixin_46075832的博客 1519

EtherCAT主站SOEM -- 15 -- CIA402伺服驱动器子协议

以上就是EtherCAT主站SOEM – 15 – CIA402伺服驱动器子协议的内容。有不明白的地方欢迎留言;有建议欢迎留言,我后面编写文档好改进。创作不容,如果文档对您有帮助,记得给个赞。

常驻客栈的博客--嵌入式EtherCAT 2733

Codex 100个真实案例 - 用AI做英语单词计划学习工具(记忆曲线+测验)

背单词是英语学习的基本功,但市面上的背单词 APP 要么收费、要么广告太多。本案例用 Codex 从零打造一个 **英语单词计划学习工具**,实现 SM-2 间隔重复算法(Anki 的核心算法)、单词本增删改查、多种测验模式(选择题/拼写/听写)、TTS 发音播放,以及学习数据的可视化统计图表。全程用自然语言驱动 Codex,用 Python 写后端逻辑 + 终端 UI,打造你的私人背单词助手!

yueyeguzhuo的专栏 201

阶乘二进制表示末尾1的位置

阶乘二进制表示末尾1的位置 题目描述 给定一个非负整数N,如果用二进制数表达N!的结果,返回最低位的1在哪个位置上,认为最右的位置为位置0。 输入描述: 第一行一个整数N。 输出描述: 输出一个整数表示答案 示例1 输入 1 输出 0 说明 1! = 1,最低位的1在0位置上 示例2 输入 2 输出 1 说明 2 != 2,最低位的1在1位置上 示例3 输入 1000000000 输出 999999987 备注: 1⩽N⩽10181 \leqslant N \leqslant 10^{18}

MIC10086的博客 429

智能车图像处理9-进阶篇1--中线的提取

(1)10-50行 基础扫线 (2)56-71 断行0 ,就是比如遇到十字,十字路口下方 第一次断线的地方。 (3)83-124 按照原先有效行,拟线作为中值,然后从中值向左右扫线,同时计算赛道宽度。 (4)125-138 如果出现赛道宽度小于先前有效行,则找到二次扫线的起点,从二次扫线起点处,继续向下扫线,直至结束,同时记录最后的有效行。 (5) 310-- 最后计算左右边线类似于方差的值,用于环岛的判断 ***这里着重描述一下二次扫线,希望大家可以理解的深刻

taiyuezyh的博客 1万+

ACM_数论_阶乘N!的末尾有几个零

首先阶乘的一个常识要知道就是25!的末尾6位全是0; 前言: 《编程之美》这本书,爱不释手!  问题描述: 给定一个整数N,那么N的阶乘N!末尾有多少个0呢?例如:N=10,N!=362800,N!的末尾有两个0;求N!的二进制表示中最低位1的位置。   问题1的求解: 分析: 解法一:        首先,最直接的算法当然是直接求出来N!然后看末尾有几个0就行了。但这里存在两个问题:

技术札记 2063

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

n!阶乘末尾有多少个零0

题目: 初阶:1*2*3*……*100 求结果末尾有多少个零。 进阶: N的阶乘末尾有多少个0分析: 一般类似的题目都会蕴含某种规律或简便方法的阶乘末尾一个零表示一个进位,则相当于乘以10而10 是由2*5所得,在1~100当中,可以产生10的有:0 2 4 5 6 8 结尾的数字,显然2是确定的,因为4、6、8当中都含有因子2,所以都可看当是2,那么关键在于5的数量了那么该问题的实质是要求出

TommyZht的专栏 1万+

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

1*2*3*……*100 求结果末尾有多少个零 网上的答案到底对不对

题目:1*2*3*……*100 求结果末尾有多少个零   分析:一般类似的题目都会蕴含某种规律或简便方法的,阶乘末尾一个零表示一个进位,则相当于乘以10而10 是由2*5所得,在1~100当中,可以产生10的有:0 2 4 5 6 8 结尾的数字,显然2是足够的,因为4、6、8当中都含有因子2,所以都可看当是2,那么关键在于5的数量了那么该问题的实质是要求出1~100含有多

whx5572371的博客 6869

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

求N!阶乘中结尾0的个数,或结果的二进制表示中最后一个1所在的位置

问题1:阶乘结尾0的个数 要想阶乘的结尾是0,那么这个0已经通过5的倍数乘以另一个数获得,例如:5,10,15,20,25...,同时可以注意到这样一个规律,5,10,15,20,30,35,40与某个数相乘后可以贡献1个0,而25,50,75,100...与某个数相乘可以贡献2个0,5^3, 2* 5^3, 3*5^3与某个数相乘时贡献了3个0,依次类推。同时我们注意到,在统计5,10,15,

bertzhang的专栏 4569

N的阶乘中(N!)末尾0的个数

问题1:N!中末尾0的个数?。。 思路1:N!=K x 10^M,且K不能被10整除,那么N!末尾有M个0. 思路2: 进行因数分解,N!=(2^x)x(3^y)x(5^z)..., 由于10=2x5,所以0的个数M只跟x和z有关,且M=min(x,z), 因为能被2整除的数出现的频率比能被5整除的数高得多,所以x>z,所以M=z。 解法1: #include int main() {

jxfang的专栏 1312

如何确定一个N!末尾有多少个零

题目:1*2*3*……*100 求结果末尾有多少个零   分析:一般类似的题目都会蕴含某种规律或简便方法的,阶乘末尾一个零表示一个进位,则相当于乘以10而10 是由2*5所得,在1~100当中,可以产生10的有:0 2 4 5 6 8 结尾的数字,显然2是足够的,因为4、6、8当中都含有因子2,所以都可看当是2,那么关键在于5的数量了那么该问题的实质是要求出1~100含有多

小试牛刀 5352

1024! 末尾有多少个0?

先把答案贴出来,具体证明在下面…… 末尾0的个数取决于乘法中因子2和5的个数。显然乘法中因子2的个数大于5的个数,所以我们只需统计因子5的个数。 是5的倍数的数有: 1024 / 5 = 204个 是25的倍数的数有:1024 / 25 = 40个 是125的倍数的数有:1024 / 125 = 8个 是625的倍数的数有:1024 / 625 = 1个 所以1024!

彦祖老师 4770

编程之美2——N!的二进制表示中最低位1的位置

任何数在计算机内部都是用二进制表示的,可以用这个特性来快速判断N!的二进制表示中最低位1的位置。 解法一: 将一个数的二进制数除以2,若二进制数的末尾是0,则能整除,否则不能整除。 因此,求 N!的二进制表示中最低位1的位置 即为求 N!中有多少个质因数2 以下为代码1: #include using namespace st

my_adu的专栏 1951

求N的阶乘N!末尾有多少个零

求N的阶乘N!末尾有多少个零 解法1: int foo(int n) { int count = 0; for(int i=1; i<=n; ++i) { int t=i; while(t%5==0) { ++count; t/=5; } } } 解法2: int foo(int n) { int count = 0; whi

kevinaxy的专栏 597

笔试算法题(33):烙饼排序问题 & N!阶乘十进制末尾0的个数二进制最低1的位置...

出题:不同大小烙饼的排序问题:对于N块大小不一的烙饼,上下累在一起,由于一只手托着所有的饼,所以仅有一只手可以翻转饼(假设手足够大可以翻转任意块数的 饼),规定所有的大饼都出现在小饼的下面则说明已经排序,则最少需要翻转几次,才能达到大小有序的结果(改变饼的顺序只能整体翻转,不能相邻交换); 分析: 假设饼大小编号为1,……,N,1就是最小的饼,N就是最大的饼,最大的N饼翻转到最下面之前,一...

weixin_34005042的博客 560

给定一个整数N,那么N的阶乘N!末尾有多少个0呢?求N!的二进制表示中最低位1的位置。

题目1:给定一个整数N,那么N的阶乘N!末尾有多少个0呢?例如:N=10,N!=3 628 800,N!的末尾有两个0。 初看这样的题目可能会想到直接求出N!的阶乘,然后再计算出0的个数。 显然用这种方法如果N很大的情况下,非常容易溢出。所以我们可以换个角度来分析这个问题。N=1×2×3×4×5×6×··· ×N我们可以对N!进行分解质因数 即N!=2x ×3y ×5z ·····

Number_0_0的博客 1177

n!的末尾0的个数

题目描述: 输入一个正整数n,求n!(即阶乘)末尾有多少个0? 比如: n = 10; n! = 3628800,所以答案为2 。 解题思路: 对于这样的问题,我们可以换个思维方式,它要求0的个数,那么0是怎么来的? 是不是一对2*5得到的0,所以我们可以分解这个问题分,把他看作是求整数n分解质因数后,一共有多少组min(2,5),在当然2的个数肯定比5多,所以我们继续往...

Demons的博客 4136

程序员面试100题之八 不要被阶乘吓倒(二进制表示中最低位1的位置 )

程序员面试100题之八 不要被阶乘吓倒(二进制表示中最低位1的位置 )

fguihbfg的博客 210
上一篇: 二进制数中1的个数
下一篇: 斐波那契(Fibonacci)数列的求法
Scandinavians
博客等级 码龄19年 36粉丝 121原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值