洛谷P1035 [NOIP2002 普及组] 级数求和
[NOIP2002 普及组] 级数求和
题目描述
已知: S n = 1 + 1 2 + 1 3 + … + 1 n S_n= 1+\dfrac{1}{2}+\dfrac{1}{3}+…+\dfrac{1}{n} Sn=1+21+31+…+n1。显然对于任意一个整数 k k k,当 n n n 足够大的时候, S n > k S_n>k Sn>k。
现给出一个整数 k k k,要求计算出一个最小的 n n n,使得 S n > k S_n>k Sn>k。
输入格式
一个正整数 k k k。
输出格式
一个正整数 n n n。
样例 #1
样例输入 #1
1
样例输出 #1
2
提示
【数据范围】
对于 100 % 100\% 100% 的数据, 1 ≤ k ≤ 15 1\le k \le 15 1≤k≤15。
【题目来源】
NOIP 2002 普及组第一题
题目解析
题目大意
题目给出一个经典的调和级数公式 S = ( 1 + 1 2 + 1 3 + 1 4 + … ) S = (1 + \frac{1}{2} + \frac{1}{3} + \frac{1}{4} + \ldots) S=(1+21+31+41+…),且易知调和函数 f ( x ) = ∫ 1 ∞ 1 x d x f(x)= \int_{1}^{\infty} \frac{1}{x}\ dx f(x)=∫1∞x1 dx发散,故调和级数不收敛,即当n→∞,有 [ S = ∑ n = 1 ∞ 1 n ] [S = \sum_{n=1}^{\infty} \frac{1}{n}] [S=∑n=1∞n1]→∞。因此对于一个确数n,必能找到最小n使得 S S S>k。
n→∞
题目分析
题目给定公式,要求求出一个最小数,将该数带入公式后所得值大于给定值。
比如给定一个数2,则有当n=4时有 S = ( 1 + 1 2 + 1 3 + 1 4 ) S = (1 + \frac{1}{2} + \frac{1}{3} + \frac{1}{4}) S=(1+21+31+41)>2。
第一想法就是使用递归函数来实现:如果S<k,则继续调用函数求和,直到找到n
或者使用do……while结构来找到n
代码题解
解法1:
#include <iostream>
using namespace std;
int findN(double k, double sum, int n)
{
if (sum >= k)
{
return n-1;
}
else
{
return findN(k, sum + 1.0 / n, n + 1);
}
}
int main()
{
double k;
cin >> k;
double sum = 0.0;
int n = 1;
int result = findN(k, sum, n);
cout << result ;
return 0;
}
解法2:
#include <iostream>
using namespace std;
int main()
{
double sum = 0;
int k = 0;
cin >> k;
double n = 0;
do
{
sum += 1/ (double)(++n);
}
while (sum <=k);
cout << n;
return 0;
}