hdu1018 Big Number
2015-08-21 23:13
232 查看
题目挺有意思。
计算n(<1e7)!的位数,一般我们会想如果知道这个数具体是多少就好办了。
然而n太大根本无法计算,其实把具体数值算出来对于求解本题是充分但非必要的条件。
我一开始考虑用把数值都用科学计数法表示出来,考虑两个浮点数相乘得到新的浮点数,更新10的幂就可以了。
然后实验过程中发现当n较大时运算的时间效率和结果的准确性均无法保证。
合理的解法是这样的。
我们假设n! = 10M, M为实数,那么显然n!的位数就等于M向下取整加一的值。
那么M = log(n!) = ∑log(i) (i ≤ n) (log指以10为底的对数)。
直观上我们可以这样理解,我们知道数值1000的位数为4这是因为log(1000) + 1 = 4,数值1001的位数为4因为(int)log(1001) + 1 = 4。
这里位数作为整数代表了原数字一部分性质。
我们推广位数到实数,使其具备原数的所有性质,即 log(i)。
那么由于对数的运算性质,数的相乘就变成了位数的相加。
结果即为所求。
http://acm.hdu.edu.cn/showproblem.php?pid=1018
View Code
计算n(<1e7)!的位数,一般我们会想如果知道这个数具体是多少就好办了。
然而n太大根本无法计算,其实把具体数值算出来对于求解本题是充分但非必要的条件。
我一开始考虑用把数值都用科学计数法表示出来,考虑两个浮点数相乘得到新的浮点数,更新10的幂就可以了。
然后实验过程中发现当n较大时运算的时间效率和结果的准确性均无法保证。
合理的解法是这样的。
我们假设n! = 10M, M为实数,那么显然n!的位数就等于M向下取整加一的值。
那么M = log(n!) = ∑log(i) (i ≤ n) (log指以10为底的对数)。
直观上我们可以这样理解,我们知道数值1000的位数为4这是因为log(1000) + 1 = 4,数值1001的位数为4因为(int)log(1001) + 1 = 4。
这里位数作为整数代表了原数字一部分性质。
我们推广位数到实数,使其具备原数的所有性质,即 log(i)。
那么由于对数的运算性质,数的相乘就变成了位数的相加。
结果即为所求。
http://acm.hdu.edu.cn/showproblem.php?pid=1018
#include <cstdio> #include <cstring> #include <cmath> using namespace std; int n; void solve(){ double M = 0; for(int i = 1; i <= n; i++) M += log10(i); int ans = (int)M; printf("%d\n", ans + 1); } int main(){ int T; scanf("%d", &T); while(T--){ scanf("%d", &n); solve(); } return 0; }
View Code
相关文章推荐
- 同一个变量打印char类型和unsigned char 类型,引发的思考
- memcpy 和 memmove 函数
- CAS服务端取消https验证
- redis cluster 集群重启关闭
- 自定义控件(五)禁止滑动的ViewPager
- 新手必须知道的13个Xcode小技巧
- 鸟哥的Linux私房菜-----14、磁盘配额
- 《花千骨》为何被批“脑残”还能创造收视神话?
- 堆区和栈区的区别
- 【LeetCode】(172)Factorial Trailing Zeroes(Easy)
- grub修复
- PAT 1010 月饼
- 多线程在python中的使用 thread
- HttpURLConnection和HttpClient
- 欢迎使用CSDN-markdown编辑器
- 马上开学了
- 谈谈 OC 中的内联函数
- 杀毒与免杀技术详解之二:特征码定位-工具及原理
- dp+trie nbut1222 English Game
- 递归