hdu1018 - Big Number
来源:互联网 发布:电机软件控制工程师 编辑:程序博客网 时间:2024/05/18 03:50
地址
http://acm.hdu.edu.cn/showproblem.php?pid=1018
定位
同题不同解
数学推导
分析
此题与hdu1042题目内容相似,都是
n!
问题,考察内容却大相径庭。解法也完全不同。hdu1042,要求打印
n!
的计算结果,输入规模104 ,时间限制10ms。hdu1018,要求打印
n!
的结果位数,输入规模107 ,时间限制1ms。
对比发现,hdu1042时间相对充足,主要难点在大数存储;hdu1018时间限制明显,先计算结果再输出位数的朴素思路不能满足题目要求。
虽然此题题目名为“Big Number”,但是解题策略和大数没有丝毫关系。此题为纯粹的数学问题,这里有2种解题思路。
取对数,变乘法为对数加法,时间复杂度
O(n) 。n!=10m+O(1)
化简得m+O(1)=log10n!
即m=⌊log101+log102+…+log10n⌋+1 利用Stirling公式,时间复杂度
O(1) 。n!≈2πn−−−√(ne)n
化简得lnn!=nlnn−n+0.5ln(2πn) log10n!=lnn!ln10=nlnn−n+0.5ln(2πn)ln10
即m=⌊nlnn−n+0.5ln(2πn)ln10⌋+1
解题一
代码
#include <stdio.h>#include <stdlib.h>#include <math.h>int main(){ int T,n,i; double sum; scanf("%d*c",&T); while(T--) { scanf("%d*c",&n); sum = 0.0; for(i=1;i<=n;i++) { sum += log10(i); } printf("%d\n",(int)sum+1); } return 0;}
性能
解题二
代码
#include <stdio.h>#include <stdlib.h>#include <math.h>#define PI 3.14159265int main(){ int T,n,i; double len; scanf("%d*c",&T); while(T--) { scanf("%d*c",&n); len = (n*log(n)-n+log(2*n*PI)/2.0)/log(10); printf("%d\n",(int)len+1); } return 0;}
性能
总结
预估问题规模
通过本题,可以深刻得体会阶乘运算结果位数之多。本题应适合在hdu1042之前做,因为本题就是在做预估问题规模的事情。
在做hdu1042时,我就因为没有缜密得预估存储规模吃了大亏。不预估问题规模,所谓大数大到什么程度还是不知道,模拟十进制能满足吗?不能就要模拟千进制、万进制。
总之,选定正确解题策略的前提是对问题规模的准确预估。
Thanks everyone
- HDU1018 Big Number
- HDU1018 Big Number
- hdu1018-Big Number
- poj1423 hdu1018 Big Number
- hdu1018 Big Number
- HDU1018 Big Number
- hdu1018 Big Number
- hdu1018 big number
- HDU1018 Big Number
- HDU1018(Big Number)
- HDU1018 Big Number
- hdu1018 Big Number
- hdu1018 big number
- hdu1018 - Big Number
- HDU1018-Big Number
- hdu1018—Big Number
- HDU1018 Big Number
- 求阶乘--hdu1018--Big Number
- windows下编译libuv
- sap s/4hana
- Codeforces 749A-Bachgold Problem
- 蓝桥杯 叠骰子(动态规划)
- strcpy sprintf memcpy 区别
- hdu1018 - Big Number
- 人工智能和机器学习领域的一些有趣的开源项目
- 数据库去重
- 理解Java中的弱引用
- set -o vi 搜索历史命令
- GD 验证码类
- CSRF(跨站请求伪造)攻击
- hdu2955 Robberies(另一种01背包)
- Spring xml配置实例