题目地址:http://lightoj.com/volume_showproblem.php?problem=1234
求f(n)=1/1+1/2+1/3+…+1/n的值
方法一:公式法~~(不百度,想不出来)~~
f(n)=ln(n)+1/2n+C(欧拉常数)(实用于n较大时)
C=0.57721566490153286060651209
n小于等于1e4时,打表;大于时,用公式。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
#define r 0.57721566490153286060651209
using namespace std;
double f[10006];
void init()
{
f[1]=1;
for(int i=2;i<=10000;i++)
{
f[i]=f[i-1]+(1.0/i);
}
}
int main()
{
int t,ans;
init();
scanf("%d",&t);
ans=1;
while(t--)
{
int n;
scanf("%d",&n);
printf("Case %d: ",ans);
if(n<=10000)
printf("%.10lf\n",f[n]);
else
{
double x=log(n)+r+1.0/(2*n);
printf("%.10lf\n",x);
}
ans++;
}
return 0;
}
方法二:打表
直接打表会爆内存,可以选择每一百个数打一下,数组就是1e6,单个运算最多100。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
#define r 0.57721566490153286060651209
using namespace std;
double f[1000006];
void init()
{
f[0]=0;///每一百记录一下 f[i] 实际上是f(100*n)的值
for(int i=1;i<=1000000;i++)
{
f[i]=f[i-1];
for(int j=1;j<=100;j++)
{
f[i]+=1.0/(j+i*100-100);
}
}
}
int main()
{
init();
int t,ans,n;
double sum;
ans=1;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
printf("Case %d: ",ans);
sum=f[n/100];
for(int i=1;i<=n%100;i++)
{
sum+=1.0/(n/100*100+i);
}
ans++;
printf("%.10lf\n",sum);
}
return 0;
}