Harmonic Number 求Hn; Hn = 1 + 1/2 + 1/3 + ... + 1/n; (n<=1e8) T<=1e4; 精确到1e-8; 打表或者调和级数

/**
题目:Harmonic Number
链接:https://vjudge.net/contest/154246#problem/I
题意:求Hn; Hn = 1 + 1/2 + 1/3 + ... + 1/n; (n<=1e8) T<=1e4; 精确到1e-8;
思路:由于1e8,所以直接存表不行。
通过每100个存入数组一个变量值。然后每次查询最多100次就可以了。

其他解法转自http://www.cnblogs.com/shentr/p/5296462.html:
知识点:

调和级数(即f(n))至今没有一个完全正确的公式,但欧拉给出过一个近似公式:(n很大时)
f(n)≈ln(n)+C+1.0/(2*n)
欧拉常数值:C≈0.57721566490153286060651209
c++ math库中,log即为ln。

公式:f(n)=ln(n)+C+1.0/(2*n);
n很小时直接求,此时公式不是很准。

*/

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn = 1e4+10;
const int N = 1e8;
double a[1000001];


void init()
{
    double p = 0;
    for(int i = 1; i <= N; i++){
        p += 1.0/i;
        if(i%100==0)
            a[i/100] = p;
    }
}
int main()
{
    int T, n, cas=1;
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    init();

    cin>>T;
    while(T--)
    {
        scanf("%d",&n);
        double p = 0;
        for(int i = n/100*100+1; i <= n; i++){
            p += 1.0/i;
        }
        printf("Case %d: %.10lf\n",cas++,p+a[n/100]);
    }

    return 0;
}
/**
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const double C=0.57721566490153286060651209;
double a[10004];
void init()
{
    for(int i = 1; i <= 10000; i++){
        a[i] = a[i-1]+1.0/i;
    }
}
int main()
{
    int T, n, cas=1;
    init();
    cin>>T;
    while(T--)
    {
        scanf("%d",&n);
        printf("Case %d: ",cas++);
        if(n<=10000){
            printf("%.10lf\n",a[n]);
        }else
            printf("%.10lf\n",log(n)+C+1.0/(2*n));
    }
    return 0;
}
*/

 

posted on 2017-03-28 17:17  hnust_accqx  阅读(340)  评论(0编辑  收藏  举报

导航