POJ 1423 解题报告
2015-05-30 04:58
337 查看
这道题不能硬算。有很多巧妙的解法。
其一是打表“硬算”,但是当大于10, 100, 1000,...,等时除以相应的10的倍数(比如大于100时除以10),这样也能统计出来位数。
解法见:http://poj.org/showmessage?message_id=173590
其二是用stirling's approximation: http://en.wikipedia.org/wiki/Stirling%27s_approximation。斯特林公式是个很好的近似,在这里套用公式就可以得到结果。
解法见:http://poj.org/showmessage?message_id=110844
还有一种也是用公式填表。
len(n!) = int(log10(2) + log10(3) + ... + log10(n)) + 1
证明也挺简单的:n! = a * 10 ^ k。其中1<=a<10。(k + 1)即为我们所要求的n!的位数(10^2有3位)。
每个数都可以写成右边的形式。
我们对两边log10,有:log10(n!) = log10(a) + k。所以k = log10(n!) - log10(a) = log10(2) + log10(3) + ... + log10(n) - log10(a) = sum - log10(a).
这里我们用sum指代log10之和。由于1<=a<10,我们有0 <= log10(a) < 1.
由于k是整数,所以sum - log10(a)就是int(sum)。所以我们要求的结果即为k + 1 = int(sum) + 1。
其一是打表“硬算”,但是当大于10, 100, 1000,...,等时除以相应的10的倍数(比如大于100时除以10),这样也能统计出来位数。
解法见:http://poj.org/showmessage?message_id=173590
其二是用stirling's approximation: http://en.wikipedia.org/wiki/Stirling%27s_approximation。斯特林公式是个很好的近似,在这里套用公式就可以得到结果。
解法见:http://poj.org/showmessage?message_id=110844
还有一种也是用公式填表。
len(n!) = int(log10(2) + log10(3) + ... + log10(n)) + 1
证明也挺简单的:n! = a * 10 ^ k。其中1<=a<10。(k + 1)即为我们所要求的n!的位数(10^2有3位)。
每个数都可以写成右边的形式。
我们对两边log10,有:log10(n!) = log10(a) + k。所以k = log10(n!) - log10(a) = log10(2) + log10(3) + ... + log10(n) - log10(a) = sum - log10(a).
这里我们用sum指代log10之和。由于1<=a<10,我们有0 <= log10(a) < 1.
由于k是整数,所以sum - log10(a)就是int(sum)。所以我们要求的结果即为k + 1 = int(sum) + 1。
thestoryofsnow | 1423 | Accepted | 39360K | 500MS | C++ | 691B |
/* ID: thestor1 LANG: C++ TASK: poj1423 */ #include <iostream> #include <fstream> #include <cmath> #include <cstdio> #include <cstring> #include <limits> #include <string> #include <vector> #include <list> #include <set> #include <map> #include <queue> #include <stack> #include <algorithm> #include <cassert> using namespace std; const int MAXM = 10000001; int length[MAXM] = {0}; int main() { double sum = 0; for (int m = 1; m < MAXM; ++m) { sum += log10(double(m)); length[m] = (int)sum + 1; } int T; scanf("%d", &T); for (int t = 0; t < T; ++t) { int m; scanf("%d", &m); printf("%d\n", length[m]); } return 0; }
相关文章推荐
- 关于质能等价的思考
- Réseau Donnée---搭建网络
- Compute all mnemonics for a phone number
- [LeetCode] Kth Largest Element in an Array 数组中第k大的数字
- 瀑布流源码
- WPA2-EAP
- 模拟 webbench 并发连接 测试网站 负载能力 《拿来主义》
- CUDA ---- GPU架构(Fermi、Kepler)
- js对象, 数组 , json 互相转换
- 5.29/C
- 《C++编程思想》 第一章 对象的演化
- DNS到底是干什么用的
- Eclipse快捷键指南
- hadoop实战–搭建eclipse开发环境及编写Hello World
- 编译hadoop eclipse的插件(hadoop1.0)
- 【leetcode】Unique Paths II
- XMPP协议分析-原理篇
- Ljava.lang.Object; cannot be cast to com.bdqn.hibernate.entity.*
- POJ 1018 解题报告
- 随笔动态生成