N!最后一位非0位的求法

计算n!的最后一位非零数字的算法  给个想法,没有具体实现,应该可以解决1M位以内的阶乘的最后非零数字问题。 当然如果超出long long的话需要用大整数的运算。 大体思想: 从n的最低位到最高位依此计算出最后一个非零数字在第k位的所有在1。。n范围内的数字所提供的2,3,7,9的个数,然后计算出总的2,3,7,9的个数,利用单个数字相乘最后一位数字的循还性,计算出n!的最后一位非零数字。 具体想法如下: 1.对于n!,考 阅读详情
本文内容遵从CC版权协议 转载请注明出自:   http://blog.youkuaiyun.com/masterluo

        PS:这篇文章是很早以前我在使用博客圆的时候写的,后来换了两次搏客,都把这篇文章拿过来了。

        问题是求关于N!的最后一位非0位, 如3!=6,最后一位非0位为6, 5!=120, 最后一位非0位为2.怎么样快速的求出最后一位非0位呢?

     最朴素的想法就是先求出N!的结果,再求出结果的最后一位非0位.当N比较小时,是可以承受的,但是当N达到一定规模的时候,时间,空间都不会太理想.这里需要一些技巧.既然是求最后一位非0位,我们就可以先除非所有对结果没有影响的数,如10的倍数.于是先把N!因子分解得到形如2^a*5^b*c.这个时候我们去掉一个b个5因子和b个2因子,最后一位非0位是不变的.(N!中2的因子一定不会比5的因子少).于是我们的要求的结果就变为(2^(a-b)*c)%10.由(a*b)%10=((a%10)*(b%10))%10我们可以得((2^(a-b)%10)*(c%10))%10,由于c不会产生未位为0,故只保留c的最未位即可.于是可将c转化为1,3,7,9因子的相乘得到的结果的最未位(因为1,3,7,9因子相乘不会产生最未非0位,故去掉高位不会对结果产生影响,同时1*n=n可以去掉1的因子).

     2,3,7,9因子规律如下:

                      2^1=2, 2^2=4, 2^3=8, 2^4=16->(6), 2^5=32->(2)

                      3^0=1, 3^1=3, 3^2=9, 3^3=27->(7), 3^4=81->(1)

                      7^0=1, 7^1=7, 7^2=49->(9), 7^3=343->(3), 7^4=2401->(1)

                      9^0=1, 9^1=9, 9^2=81->(1), 9^3=729->(9), 9^4=6561->(1)

     它们都是以4为循环周期的.于是我们只要求出2, 5, 3, 7, 9因子的个数即可.

     首先我们求2,5因子在N!中的个数.2的因子的每个偶数到少有1个,同时将数列中每个数/2,其中的偶数还有一个2因子.直至n=1或n=0结束.5因子求法相同.代码如下:

  1. int getFactor25 ( int n, int f ) {
  2.     int ret= 0;
  3.     while (n> 0 ) {
  4.         ret+=n/f;
  5.         n/=f;
  6.     }
  7.     return ret;
  8. }

     3,7,9因子的个数有多少呢?对于1,2,3,4......n-1,n来说,未尾以3,7,9结束的数的个数为n/10+(n%10³f?1:0),(f=3,7, 9).同时我们对于对于奇数数列/5可以得到一个新的数列也有3,7,9因子,对于偶数数列/2也可以得到新的数列也有3,7,9的因子,将所有的3,7,9因子相加即可得到总的3,7,9因子的个数.得到3,7,9因子的个数后,我们可以将其全部转化为因子3的个数.因为9=3*3(3^2), 7=(3*3*3(3^3))%10,设f3, f7, f9为3, 7, 9因子的个数,全部转化为因子3的个数为f3+2*f9+3*f7.

     于是我们可以用递归同时求2,3,5,7,9因子的个数,代码如下:

  1. void getFactor ( int n ) {
  2.     if (n== 0 )
  3.         return;
  4.     for ( int m=n; m> 0; m/= 5 ) {
  5.         int t=m/ 10, r=m% 10;
  6.         f3+=t+ (r>= 3 );
  7.         f5+=t+ (r>= 5 );
  8.         f7+=t+ (r>= 7 );
  9.         f9+=t+ (r>= 9 );
  10.     }
  11.     f2+=n/ 2;
  12.     getFactor (n/ 2 );
  13. }

 

     可用两个数组表示循环:

  1. int p2 [ 4 ]= { 6, 2, 4, 8 };
  2. int p3 [ 4 ]= { 1, 3, 9, 7 };

 

     故结果为(1):当2, 5因子个数相同时,只与3因子相关,结果为p3[f3%4]%10;(2):当2因子大于5因子时,结果同时与3因子和2因子相关,为(p2[f2%4]*p3[f3%4])%10.

     其实通过N!的最未非0位的方法我们可以求排列组合数NPM,C(N,M)的最未非0位,用上面的各因子个数减去下面的各因子个数就是结果的各因子个数.只是此时需要注意的是5的因子可能会比2的因子多.当5的因子比2的因子多时,未位一定为5.其余情况与上面相同. 

求n的阶乘最后非0位 最后的000是因为555和222产生的对吧,而且222的因子还比555多,因此,我们只需要知道555的因子有多少个就行了 那么我们来看555的因子有多少个 以58!58!58!为例: 58!=1⋅2⋅3⋅4⋅58!=1⋅2⋅3⋅4⋅58!=1\cdot2\cdot3\cdot4\cdot555⋅6⋅7⋅8⋅9⋅⋅6⋅7⋅8⋅9⋅\cdot6\cdot7\cdot8\cdot9\cdot101... 阅读详情

相关推荐

C语言程序:求阶层最后一个不为0的数字

题目:给定正整数N(N < 5000),计算并输出N!的最后一位非0数字。例如,当N等于5时输出2。 思路:最后一位不为0的数字,计算1到N之间能被2和5整除的数字,然后再分析

jzxx_1172 USACO 求阶乘

题目描述 阶乘的定义如下: N! = 1 * 2 * 3 * ... * N-1 * N例如, 12! = 1*2*3*4*5*6*7*8*9*10*11*12 = 479001600最右的非0位是6,后面有2个0。写一个程序计算N!最右非0位和末尾的0的个数。 输入 一个整数N, 1 输出 一行输出2个整数:最右非0位,末尾0的个数。 样例输入 12 样例输出 6 2

934

ZYNQ-7035+HMCAD1511高速数据采集系统设计

高速数据采集是电子测量、雷达信号处理与通信基带验证的核心技术基础,其性能瓶颈常集中于采样率、通道同步性与实时处理能力。基于ADC采样原理与SoC异构架构,高带宽、低抖动时钟链路与FPGA+ARM协同处理成为突破关键。ZYNQ-7035凭借275K逻辑单元与千级DSP资源,显著提升LVDS数据流吞吐与片上滤波/触发等实时算法部署能力;HMCAD1511则以1GSPS四通道同步采样和8位分辨率,满足示波器级动态范围需求。该组合广泛应用于嵌入式信号采集平台开发、教学实验系统构建及国产化仪器原型验证。

weixin_28939623的博客 262

阶乘

【USACO】阶乘 时间限制: 1 Sec  内存限制: 16 MB 题目描述 阶乘的定义如下: N! = 1 * 2 * 3 * ... * N-1 * N 例如, 12! = 1*2*3*4*5*6*7*8*9*10*11*12 = 479001600 最右的非0位是6,后面有2个0。 写一个程序计算N!最右非0位和末尾的0的个数。 输入 一个整数N, 1

梧桐下的四叶草 634

ESP32S3新手避坑:用IDF5.0驱动GT911触摸屏,我踩过的三个雷都给你填平了

本文详细解析了在ESP32S3开发板上使用IDF5.0驱动GT911触摸屏时常见的三大问题:软重启失效、状态寄存器读取异常和初始化参数差异。通过逻辑分析和硬件调试工具,提供了针对性的解决方案和优化建议,帮助开发者高效完成触摸屏驱动开发。

weixin_42567497的博客 297

从DeepMimic到虚拟偶像:用动作捕捉数据训练AI跳舞的完整流程(附Blender插件配置)

本文详细介绍了如何利用DeepMimic的深度强化学习框架,将动作捕捉数据转化为虚拟偶像或游戏角色的舞蹈动作。从核心的模仿学习理念、PyBullet环境搭建、策略网络与奖励函数设计,到数据处理、训练技巧(如参考状态初始化),最后讲解了如何将训练好的AI模型集成到Blender和Unity等工具中,实现从数据到实时驱动角色的完整流程。

weixin_29054399的博客 504

阶乘问题

题目描述 阶乘的定义如下:N!=1×2×3×...×N-1×N 例如,12!=1×2×3×4×5×6×7×8×9×10×11×12=479001600 最右的非0位是6,后面有2个0。 写一个程序计算N!最右非0位和末尾0的个数。 输入输出格式 输入格式: 一行,一个整数N。(1≤N≤1000000) 输出格式: 一行,输出2个整数:最右非0位,末尾0的个数。 输入输出样例 ...

weixin_30418341的博客 611

Claude Code 完整使用教程(2026最新版)

《Claude Code 完整使用教程(2026最新版)》摘要: Claude Code 是 Anthropic 公司推出的智能编程工具,通过自然语言对话实现代码编写、调试和重构。本教程基于 v2.1.101 版本,涵盖安装配置、核心功能及最新特性。主要内容包括: 多平台安装方式(macOS/Linux/Windows) 桌面应用专属功能如并行会话、定时任务和语音模式 模型选择指南(Sonnet/Opus/Haiku) 快速入门示例:5分钟创建Node.js项目 核心功能:代码读写、命令执行、Git集成等

程序猿_三产 2万+

求N!最后一位非零数

设f(n)表示n!的最后一位非0位d(n)表示n!中不计算5的倍数时的结果,比如d(6)=1*2*3*4*1*6m(n)表示d(n)最后一位,并且这一位一定不为0。m(n)很特殊,因为他是循环的除了n=1,其余都是按照6 2 6 4 4 4 8 4 6 6循环小于10的n,f(n)可以直接算出来,以下讨论的都是n&gt;=10的情况接下来开始计算n!=d(n)*5*10*15*...*(5*(n/...

sher杨的博客 2546

基于卷积神经网络CNN实现电力负荷多变量时序预测(PyTorch版)

随着智能电网的发展,精准的电力负荷预测对能源调度和电网稳定具有重要意义。本文基于PyTorch框架,提出一种基于卷积神经网络(CNN)的多变量时间序列预测模型,用于电力负荷的短期预测。

时序笔记 988

玩转Docker小游戏项目系列: Docker部署中国象棋网页小游戏

玩转Docker小游戏项目系列: Docker部署中国象棋网页小游戏

jks212454的博客 440

求n!最后一位非零数

引子:求n!末尾0的个数 n!末尾的0来源只有2,5两个质数相乘.所以只需要考察n!中包含多少个2和多少个5.然后取其较小值即为所求.即ans=min(cnt(2),cnt(5)).而转念一想,cnt(2)怎么可能比cnt(5)少呢?所以最终答案改为ans=cnt(5). 那么问题来了,如何求n!中5的个数呢?cnt(5)=n/5+n/25+n/125......+n/5^log5(n)...

479

11、ThingsBoard集群部署k8s

今天终于有时间去搞这个啦,拖了很久了,一直没时间,因为我本地没有那么多机器资源,开虚拟机不够,如果租用阿里云服务器,需要有充值的时间,因为这个费用是按小时付费,需要有连贯的时间来搞才行,今天恰好有时间,就开始搞了,弄成功搞出来了,特地写博客记录下来。

AldrichEugene 991

计算n!的最后一位非0的数

计算n!是一个非常难的任务,事实上n=20时,计算机的长整型就存放不了这么大的数了,但是,我们可以编写程序来算出n!的最后一位非0的数。 #include<stdio.h> int main() { int i; int x; int sum=1; printf(“please input a number:\n”); scanf("%d",&x); for(i=1;i&l...

Mamba的博客 1528

基于点云数据的统计滤波算法改进

随着三维视觉和点云处理技术的发展,点云数据在机器人、自动驾驶、增强现实等领域得到了广泛应用。而点云数据中常常包含着各种噪声和异常点,这些噪声和异常点会影响后续的数据处理和分析任务。因此,对点云数据进行滤波处理是必不可少的一步。在点云滤波算法中,统计滤波(Statistical Filtering)是一种常见且有效的方法。它通过对点云数据进行统计分析,将噪声和异常点剔除或修复,从而得到更为准确和可靠的点云数据。本文将介绍一种改进的统计滤波算法,并提供相应的源代码实现。

QfcaLinux的博客 292

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

N!最后的非零位

N!最后的非0位 5! = 1 * 2 * 3 * 4 * 5 = 120,所以5!的最后面的非零位是2; 7! = 1 * 2 * 3 * 4 * 5 * 6 * 7 = 5040,所以最后面的非零位是4。 1234!最后1个非0位是多少? #include<cstdio> #include<cstring> int main() { int n,ans=1; ...

快速乘与快速幂 297

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

23 阶乘最后的非0位

问题描述 : N的阶乘写作N!表示小于等于N的所有正整数的乘积。阶乘会很快的变大,如13!就必须用32位整数类型来存储,70!即使用浮点数也存不下了。你的任务是找到阶乘最后面的非零位。举个例子,5!=12345=120所以5!的最后面的非零位是2,7!=1234567=5040,所以最后面的非零位是4。 输入说明 : 一个不大于1000的整数N。 输出说明 : 共一行,输出N!最后面的非零位。 输...

秃头小姐姐 715

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

阶乘最后的非0位

N的阶乘写作N!表示小于等于N的所有正整数的乘积。阶乘会很快的变大,如13!就必须用32位整数类型来存储,70!即使用浮点数也存不下了。你的任务是找到阶乘最后面的非零位。举个例子,5!=12345=120所以5!的最后面的非零位是2,7!=1234567=5040,所以最后面的非零位是4。 输入说明 : 一个不大于1000的整数N。 输出说明 : 共一行,输出N!最后面的非零位。 输入范例 : 7...

cjj_123123的博客 486

n位逐位整除数

n位逐位整除数n位逐位整除数是什么开辟空间并初始化判断已取的 n位数能否被 n 整除r取值的含义输出条件设置总代码与输出示例: n位逐位整除数是什么 n位逐位整除数(简称整除数):从其高位开始,高1位能被整数1整除(显然),高2位能被整数2整除,…,整个n位能被整数n整除。给定整数n,求所有的n位整除数的个数。 形如123258,前一位 1 自然能被1整除;前二位为12,也能被2整除;前3位为12...

weixin_43786637的博客 5324

POJ-1150(求排列数P(n,m)中最后一个非0的数字)

1.如何求出n阶乘中质因数x(比如说5)出现的次数? int get(int m, int n)//计算n!中质因子m的出现次数   {       if (n == 0) return 0;       return (n / m) + get(m, n / m);   }  解析: 求n!中m出现的次数。那么n可以分解为 即为求q的值。 例如:假

3206

求n!的最后一位非零数

#include void main() { int res[4][4] = {{2,6,8,4}, {4,2,6,8}, {6,8,4,2}, {8,4,2,6}}; int table[10] = {6,6,2,6,4,4,4,8,4,6}; unsigned n; int t = 1, sum = 0; scanf("%u", &n); if(n == 0

Javkburd的专栏 1620

记一个有趣的算法题:求n的阶乘最后一位非零数字

今天领导录题的时候问了一个题,使我陷入了迷茫。原题目是这样的:给出n,求n的阶乘的结果的最后一位非零数字,和末尾0的个位数。例如n=12n=12n=12, 则n!=1×2×...×12=479001600n!=1\times 2\times ... \times 12=479001600n!=1×2×...×12=479001600,则其最后一位非零数字为6,末尾0的个数为2。 思路1(正确) 这个思路是领导刚问我时我首先想到的,但是是一个比较笨而且复杂度较高的方法。时间复杂度O(n(logn)2)O(n(

雪的期许 3336

N!(N的阶乘)最末位非0的求解方法

关于N!的最后一位非0位, 如3!=6,最后一位非0位为6, 5!=120, 最后一位非0位为2.怎么样快速的求出最后一位非0位呢?

在思索中前行! 5623

C语言——n阶乘的最后非0位

题目如图 解题思路: 如果直接输出阶乘再求最后非零数,阶乘过大,会出现溢出的情况,因此在每次求阶乘的时候会把数截取掉,然后在缩放 #include <stdio.h> #include <math.h> int main(){ int i,n,sum=1; scanf("%d",&n); if(n==0) printf("%d",sum); else...

weixin_44252790的博客 1280
上一篇: 解方程: x+y=x|y
下一篇: 求正整数中第K个二制中不含11的数
MasterLuo
博客等级 码龄18年 33粉丝 15原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值