题意:对一个正整数n(n <= 10^8),求Σ(1/k) (1<=k<=n)。
题解:分步打表
1.1e8太大了数组开不下,所以想到缩小100倍,开一个1e6的数组。即计算每个x(x%100=0)对应的求和值。
2.然后对于一个输入的x值可由已计算的数加上不超过100次的计算得到。
#include<stdio.h>
#include<string.h>
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<vector>
#define maxn 100000005
using namespace std ;
double sum[1000005] ;
void init() //分步打表法第1步
{
int i ;
double ans = 0 ;
sum[0] = 0 ;
for(i = 1 ; i <= maxn - 5 ; i ++)
{
ans += 1 / double(i) ;
if(i % 100 == 0) //将打表大小缩小100倍
sum[i / 100] = ans ;
}
}
int main()
{
int t , n , x ;
int i , j , k ;
int begin , end ;
int cnt = 0 ;
double ans ;
init() ;
scanf("%d" , &t) ;
while(t --)
{
scanf("%d" , &n) ;
begin = n / 100 * 100 + 1 ;
end = n / 100 * 100 + n % 100 ;
ans = sum[n / 100] ;
//分步打表法第2步
for(i = begin ; i <= end ; i ++) //1个数最多计算100次
ans += 1 / double(i) ;
printf("Case %d: %.10lf\n" , ++cnt , ans) ;
}
}