阶乘数最右边一个非零数字:通用解法
来源:互联网 发布:激光雕刻切割机软件 编辑:程序博客网 时间:2024/06/06 07:44
做题时发现了一个奇怪的问题:给出正整数n (可能有前导0),请求出n! 最右非零的数位的值。那么这道题肿么做呢???
USACO中有一道类似的题目,不过数据范围要小很多。。。n 只有106 ,直接一个爆搞取模 1000000 即可但是这道题中数据范围有10100 ,暴力的话。。。估计没有那么几个世纪是运行不出来的。。。考试的时候也没有想出什么好的方法,就暴力(暴力大法好)搞了10分。。
然后考试后,根据lyc大爷的博客 http://luoyuchu.logdown.com/posts/257468-oi-seeking-n-the-right-of-non-zero-numbers 写出了一份代码,但是又发现owaski大爷有一种更好的算法,于是继续学习
PS:其实这种算法应该说是一种数学做法,是别人从数竞书上看到的。。。
首先我们知道一点,因为1 到n 中2 的因子一定比5 的因子多,所以求 n! 的末尾0 的个数的做法就是找1 到n 中有多少个5 的因子,也就是说
有一些奇怪的方法得知,这个最右非零的数位上的数一定是一个偶数,也就是2,4,6,8 中的一个。
设n=5k+t ,n! 最右非零的数位的值为f(n) ,因为有以下式子:
也就是说,f(n) 为12k∗(1∗2∗3∗4)∗(6∗7∗8∗9)∗...∗[(5k−4)∗(5k−3)∗(5k−2)∗(5k−1)]∗k!∗t!的最后一位。
我们忽略k! 和t! 继续化简,可以得到:
很明显答案一定是偶数,所以如果f(n)mod5 为奇数的话f(n)mod10=f(n)mod5+5 ,而f(n)mod5 为偶数的话f(n)mod10=f(n)mod5 ,对于k! 我们可以进行同样的操作,直到此数小于5 为止。
下面进行一个模拟操作,我们拿104做例子
经过暴力程序的验证,这个答案是正确的,在经过各种对拍,可以确定这就是正解!!!
下面不附上代码。。。因为长得丑。。。233
0 0
- 阶乘数最右边一个非零数字:通用解法
- 阶乘最右边非0数
- 求阶乘的最右一位非零数字
- 获取阶乘n!的最后一个非零数字
- 阶乘最右边的非0位
- 蓝桥杯练习——C++输出阶乘的最右边一位非零数
- python求解一个数的阶乘有几个零
- 求一个数阶乘末尾有几个零
- n的阶乘最后一个非0的数
- USACO-Factorials(阶乘最后一个非0数)
- 找N!最后一个非零的数字
- 杭电1066-N!的最后一个非零数字
- 题目:在数组中,数字减去它右边的数字得到一个数对之差。
- 1066N !最右边非零数
- N^N 数字的最右边
- Problem F: 最右边的数字
- POJ 1401 求一个数的阶乘结果后零的个数
- 用JAVA程序编写实现求一个阶乘数的得数末尾有几个零
- 3.15打击假冒网站,就用 “沃通国际认证”
- Makefile伪目标
- 在非越狱设备上使用 LLDB 调试第三方 App
- 最长公共子序列LCS递归解法
- android camera(一):camera模组CMM介绍
- 阶乘数最右边一个非零数字:通用解法
- 把iptables移植到嵌入式Linux系统
- ORACLE定时任务个人使用记录(job)
- LinkedHashMap
- 热编译工具fswatch
- Nginx+Tomcat+Memcached集群Session共享
- 大数据的显示
- Mac下vim插件taglist的一个小问题
- qt 线程更新UI界面