Harmonic Number LightOJ

来源:互联网 发布:暴走漫画淘宝旗舰店 编辑:程序博客网 时间:2024/05/02 03:10

In mathematics, the nth harmonic number is the sum of the reciprocals of the firstn 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 than10-8 will be ignored.

Sample Input

12

1

2

3

4

5

6

7

8

9

90000000

99999999

100000000

Sample Output

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




  题解 用到一个公式f(n)=1+1/2+1/3+1/4.....+1/n(调和级数)

           f(n)≈ln(n)+r+1/(2*n)     r为欧拉常数  r=0.57721566490153286060651209


       调和级数点击打开链接

     由于函数在n=1 时误差为-0.0382064988721671,n(2,7)时误差为0.0257360642441862~0.0106247817461118,n>=7时误差为0.00942087240133116左右,n>=70 时0.000998481033276377左右n特别大时逐渐时趋于0。当n比较小,误差在1e-8之内,所以在n比较小的时候用打表解决。。



 

#include<cstdio>#include<cstring>#include<cmath>using namespace std;const double r=0.57721566490153286060651209;int t,n,k;double a[100000];int main(){    k=0;    a[0]=0.0;    a[1]=1.0;    for(int i=2;i<100000;i++)    {        a[i]=a[i-1]+1.0/i;    }    scanf("%d",&t);    while(t--)    {        scanf("%d",&n);        if(n<100000)            printf("Case %d: %.10lf\n",++k,a[n]);        else        {            double ans;            ans=log(n)+r+1.0/(2.0*n);//math库中,log就是以ln为底            printf("Case %d: %.10lf\n",++k,ans);        }    }    return 0;}

解法二:可以打表 ,以50个数记录一个结果,这个可以化简时间复杂度 (看大神这么写的,这种思路很好,想不到公式,可以用打表解决)


#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int M=2000000+10;double a[M];int t,n;void init(){    double s=0.0;    for(int i=1;i<=100000000;i++)    {        s=s+1.0/i;        if(i%50==0)            a[i/50]=s;    }}int main(){    double ans;    int k=1;    init();    scanf("%d",&t);    while(t--)    {        scanf("%d",&n);        int m=n/50;        ans=a[m];        for(int i=m*50+1;i<=n;i++)        {            ans+=1.0/i;        }        printf("Case %d: %.10lf\n",k++,ans);    }    return 0;}


原创粉丝点击