LightOJ:1234 - Harmonic Number (调和级数求和)

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

Output for Sample Input

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

题意分析:

\frac{1}{1}+\frac{1}{2}+\frac{1}{3}+...+\frac{1}{n}

解题思路:

有一个公式\frac{1}{1}+\frac{1}{2}+\frac{1}{3}+...+\frac{1}{n} = ln(n+1)+e, e是欧拉常数,但是这公式并不精确。

所以打表会好一点,

直接打表会暴内存,所以每100个打一个表,不够100的再直接计算。

#include <stdio.h>
#define N 1000002
double ans[N];
int main()
{
	int T, t=0, n;
	for(int i=1; i<N*100-10; i++)
	{
		ans[i/100+1]+=1.0/i;
		if(i%100==0)
		{
			ans[i/100+1]+=ans[i/100];
			ans[i/100]+=1.0/i;
		}
	}
		
	scanf("%d", &T);
	while(T--)
	{
		scanf("%d", &n);
		double sum=0;
		for(int i=n/100*100+1; i<=n; i++) 
			sum+=1.0/i;
		printf("Case %d: %.10lf\n", ++t, sum+ans[n/100]);
	}
	return 0;
} 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
这是一个调和级数,可以表示为: 1 - 1/2 + 1/3 - 1/4 + ... + (-1)^(n-1) * 1/n 这个级数的部分和可以用以下公式计算: S_n = 1 - 1/2 + 1/3 - 1/4 + ... + (-1)^(n-1) * 1/n 如果你不知道这个公式是怎么来的,可以参考一下调和级数的性质。 现在我们来计算一下前n项和: S_n = 1 - 1/2 + 1/3 - 1/4 + ... + (-1)^(n-1) * 1/n S_n = 1 + (1/2 - 1/2) + (1/3 - 1/4) + (1/5 - 1/6) + ... + [(1/(2k-1)) - (1/2k)] S_n = 1 + 1/2 - 1/3 + 1/4 + ... + [1/(2k-1) - 1/(2k)] S_n = 1 + 1/2 + 1/3 + ... + 1/(2k-1) - 1/2 - 1/4 - ... - 1/2k 这个式子里面有两个调和级数,一个是前k项的奇数调和级数,另一个是前k项的偶数调和级数。它们的部分和可以分别表示为: H_k = 1 + 1/2 + 1/3 + ... + 1/k G_k = 1/2 + 1/4 + ... + 1/2k 所以原式可以写成: S_n = H_n - G_k 现在我们来计算一下H_n和G_k: H_n = 1 + 1/2 + 1/3 + ... + 1/n G_k = 1/2 + 1/4 + ... + 1/2k H_n和G_k都是调和级数,它们的部分和可以用对数函数来表示。具体来说,我们有: ln(n+1) < H_n < 1 + ln(n) ln(2k+1) < H_k < 1 + ln(2k) ln(2k+1) - ln(2) < G_k < ln(2k+1) 所以我们可以用对数函数来计算H_n和G_k的近似值。具体来说,我们有: H_n ≈ ln(n) + γ G_k ≈ ln(2k) + γ - ln(2) 其中γ是欧拉常数,约等于0.5772156649。 现在我们可以用这些公式来计算S_n了。具体步骤如下: 1. 计算H_n和G_k的近似值,即: H_n ≈ ln(n) + γ G_k ≈ ln(2k) + γ - ln(2) 2. 计算S_n,即: S_n = H_n - G_k 3. 把结果四舍五入到合适的精度。 下面是Python代码实现: import math def harmonic_series(n): """计算前n项调和级数的部分和""" s = 0 for i in range(1, n+1): s += 1 / i return s def alternating_harmonic_series(n): """计算前n项交错调和级数的部分和""" s = 0 for i in range(1, n+1): s += (-1) ** (i-1) / i return s def harmonic_series_approx(n): """计算前n项调和级数的近似值""" return math.log(n) + 0.5772156649 def alternating_harmonic_series_approx(n): """计算前n项交错调和级数的近似值""" return math.log(2*n) + 0.5772156649 - math.log(2) def sum_of_alternating_harmonic_series(n): """计算前n项交错调和级数的部分和""" hn = harmonic_series_approx(n) gk = alternating_harmonic_series_approx(n) return hn - gk n = int(input("请输入n的值:")) s = sum_of_alternating_harmonic_series(n) print("前{}项交错调和级数的部分和为:{:.6f}".format(n, s))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张宜强

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值