lightoj1234——调和级数+欧拉常数
題目鏈接:http://lightoj.com/volume_showproblem.php?problem=1234
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
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
?
題目翻譯:
求1/n+2/n+3/n+....+n/n的值,保證誤差不小于1e-8;
可以用公式來求(可以百度一下),比較直接,不過需要自己再補一個誤差值(1.0/2*n)。
#include<iostream> #include<cmath> using namespace std; const double r=0.57721566490153286060651209; //歐拉常數 const int maxn=1e4; double sum[maxn]; void init(){sum[1]=1.0; for(int i=2;i<=maxn;i++)sum[i]=sum[i-1]+1.0/i; } int main(){int T,n;scanf("%d",&T);init();for(int kcase=1;kcase<=T;kcase++){scanf("%d",&n);if(n>maxn){double ans=log(n)+r+1.0/(2*n);printf("Case %d: %.10lf\n",kcase,ans);}else printf("Case %d: %.10lf\n",kcase,sum[n]);}return 0; }最簡單的方法是每隔50個存儲一個值(保證不會超時),然后在求的時候,找到最近的一個存儲的值,從這個值開始遞推求最終值。(跑一個網上的代碼實現)
#include <iostream> #include <cstdio> using namespace std; #define MAX 100000000 double ans[2000100]; int main() {int t,n,k;int casenum;casenum=0;double sum=0.0;k=0;ans[0]=0;for(int i=1;i<=MAX;i++){sum+=1.0/i;if(i%50==0){ans[++k]=sum;}}scanf("%d",&t);while(t--){scanf("%d",&n);int num=n/50;double s;s=ans[num];for(int i=50*num+1;i<=n;i++)s+=1.0/i;printf("Case %d: %.10lf\n",++casenum,s);}return 0;}其實我自己最初寫的代碼,感覺也是可以AC的(但是不知道為啥子WA了?QAQ),也很好理解,就是對前1e6的用前綴和維護,判斷給的數是否大于1e6,如果大于就遞推求,感覺不會超時,也不會炸,但是不知道就是過不了(在炸和超時之間轉換),有知道的可以評論一下我。萬分感激!!!
錯誤代碼如下:
#include<iostream> using namespace std; const int maxn=1e6; double sum[maxn]; void init(){sum[1]=1.0; for(int i=2;i<=maxn;i++)sum[i]=sum[i-1]+1.0/i; } int main(){int T,n;scanf("%d",&T);init();for(int kcase=1;kcase<=T;kcase++){scanf("%d",&n);if(n>maxn){double ans=sum[maxn];for(int i=maxn+1;i<=n;++i)ans+=1.0/i;printf("Case %d: %.10f\n",kcase,ans);}else printf("Case %d: %.10f\n",kcase,sum[n]);}return 0; }?
?
?
?
總結
以上是生活随笔為你收集整理的lightoj1234——调和级数+欧拉常数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Linux】Linux中755权限是什
- 下一篇: eclipse快捷键总结