题目链接:https://vjudge.net/problem/LightOJ-1234
Time Limit: 3 second(s) | Memory Limit: 32 MB |
In mathematics, the nth harmonic number is the sum of the reciprocals of the first n natural numbers:
In this problem, you are given n, you have to find Hn.
Input
Input starts with an integer T (≤ 10000), denoting the number of test cases.
Each case starts with a line containing an integer n (1 ≤ n ≤ 108).
Output
For each case, print the case number and the nth harmonic number. Errors less than 10-8 will be ignored.
Sample Input |
Output for Sample Input |
12 1 2 3 4 5 6 7 8 9 90000000 99999999 100000000 |
Case 1: 1 Case 2: 1.5 Case 3: 1.8333333333 Case 4: 2.0833333333 Case 5: 2.2833333333 Case 6: 2.450 Case 7: 2.5928571429 Case 8: 2.7178571429 Case 9: 2.8289682540 Case 10: 18.8925358988 Case 11: 18.9978964039 Case 12: 18.9978964139 |
题意:
对于一个数n,输出 sigma(1/k),1<=k<=n。
题解:
1.一开始想离线做,结果发现输入完一个测试数据就必须输出,不能离线。
2. 由于n<=1e8,开一个1e8大小的数组是不可能的,那么可以尝试开一个1e6的数组,然后每隔100就存一个数据,分区打表。
3.假设能开1e8大小的数组,那么经过预处理后,那么查询只需O(1),这种处理方式是完全偏向于时间;如果不开数组,每次都重新计算,那么每次查询需O(n),而n可高达1e7,这种处理方式完全偏向于空间。可见两种极端的处理方式都无法解决问题,而需在这两者之间作个权衡,人生也如此!
代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <vector> 6 #include <cmath> 7 #include <queue> 8 #include <stack> 9 #include <map> 10 #include <string> 11 #include <set> 12 using namespace std; 13 typedef long long LL; 14 const int INF = 2e9; 15 const LL LNF = 9e18; 16 const int mod = 1e9+7; 17 const int MAXM = 1e5+10; 18 const int MAXN = 1e6+10; 19 20 double table[MAXN]; 21 void init() 22 { 23 double s = 0; 24 for(int i = 1; i<=100000005; i++) 25 { 26 s += 1.0/i; 27 if(i%100==0) table[i/100] = s; 28 } 29 } 30 31 int main() 32 { 33 init(); 34 int T, n, kase = 0; 35 scanf("%d", &T); 36 while(T--) 37 { 38 scanf("%d", &n); 39 double s = table[n/100]; 40 for(int i = n/100*100+1; i<=n; i++) 41 s += 1.0/i; 42 43 printf("Case %d: %.10f ", ++kase, s); 44 } 45 }