lightoj-1234-调和级数

来源:互联网 发布:大数据怎么搜索 编辑:程序博客网 时间:2024/05/22 14:58

题目传送门:https://vjudge.net/problem/LightOJ-1234


方法一:(有点投机取巧了大笑

公式如下:

  

其中r为常数,r=0.57721566490153286060651209(r就是欧拉常数)

but n大的时候,精确度才高。所以数小的时候就打表。

特别注意,由于题目要求精度为10^-8,常数r为有限位数,所以正常利用这个公式,并不能达到精度要求。经尝试,在原公式的基础上,再减去一个1.0/(2*n)恰好可以满足精度。((⊙o⊙)…好像比赛的话,要gg)


ac代码:

#include <algorithm>#include <iostream>#include <cstdlib>#include <cstring>#include <cstdio>#include <cctype>#include <string>#include <vector>#include <queue>#include <cmath>#include <stack>#include <map>#include <set>#define N 200005#define ll long longusing namespace std;  #define R 0.57721566490153286060651209    double ans[10010];  int main()  {      int t,n,casenum=0;      double sum;      ans[1]=1;      for(int i=2; i<=10000; i++)      {          ans[i]=ans[i-1]+1.0/i;      }      scanf("%d",&t);      while(t--)      {          scanf("%d",&n);          if(n<=10000)          {              printf("Case %d: ",++casenum);              printf("%.10lf\n",ans[n]);          }          else          {              sum=log(n+1)+R-1.0/(2*n);              printf("Case %d: ",++casenum);              printf("%.10lf\n",sum);          }      }      return 0;  }  

但是,题目主要考查一种打表和地腿的方法。没50个为一组,这样打表我们接受,然后在进行递推。


ac代码:

#include <algorithm>#include <iostream>#include <cstdlib>#include <cstring>#include <cstdio>#include <cctype>#include <string>#include <vector>#include <queue>#include <cmath>#include <stack>#include <map>#include <set>#define N 100000000#define ll long longusing namespace std;double ans[2000100];int main(){    int t,n,cas = 1, k = 1;    double sum = 1;    ans[0] = 0.0;    for(int i = 2; i <= N; i++)    {        sum = sum + 1.0 / i;        if(i%50 == 0)            ans[k++] = sum;    }    scanf("%d",&t);    while(t--)    {        scanf("%d",&n);        int shu = n / 50;        double num = ans[shu];        for(int i = 50 * shu + 1; i <= n; i++)        {            num += 1.0 / i;        }        printf("Case %d: %.10lf\n", cas++, num);    }    return 0;}