PTA|基础编程题目集|7-15
解题
循环判断当前项是否大于给定阈值,大于就将当前项累加到结果中,否则继续。
如何计算当前项?
-
分子、分母直接简单累乘后相除不符合题目要求,会超出范围 -
分子分母约分化简后再相除,如何化简?
-
观察通项:
\[\frac{n!}{3*5*7*...*(2n+1)} \]分子是
n!
,分母是奇数累乘。等价表示如下:\[\frac{1*2*3*4*5*...*n}{3*5*7*...*(2n+1)} \]分子与分母之间有共同的约数(奇数):3,5,7....。分子分母化简后就形如:
-
化简通项
n为偶数,分母小于n的因子都被约掉了
\[\frac{2*4*6*...*n}{(n+1)*...*(2n+1)} \]n为奇数, 分母小于等于n的因子被约掉了
\[\frac{2*4*6*...*(n-1)}{(n+2)*...*(2n+1)} \]-
相除计算
根据化简后的通项公式,可以求出每一项的值。但是对于这样的问题,后一项与前一项之间存在一定的递进关系,各自单独求出每一项,势必存在重复的计算,不够明智,很自然的想法是期望在上一项的基础上,进行少量的运算即可得出当前项的结果。
类似我们求解1!+2!+3!+...+n!
-
是否可行呢,我们先看具体的项数(n=4,5,6)情况。
n=4
\[\frac{2*4}{5*7*9}
\]
n=5
\[\frac{2*4}{7*9*11}
\]
n=6
\[\frac{2*4*6}{7*9*11*13}
\]
观察可知,分子变化相对简单——因子只增加,而分母的因子存在增加和减少的情况。
若n为偶数,分母增加的因子是(2*n+1)
,分子增加因子n
若n为奇数,分母增加的因子是2*n+1
,减少的因子是n
,分子不变。
接下来通过具体的代码去实现。
关键点
每一项的分子与分母类型为 long long int
,需要将分子与分母化简后再计算,不能直接各自求积相除,否则报错。
参考代码
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
float f,total=0;
cin>>f; //给定阈值
int n=0;
long long int mo=1,de=1; //mo为分子,de为分子
float temp=(mo*1.0/de);
while(temp>=f) //小于阈值时停止
{
total+=temp; //结果累加
n++;
if(n%2==0) //n为偶数时分母、分子计算
{
mo*=n;
de*=(2*n+1);
}
else //n为奇数时分母、分子计算
{
de/=n;
de*=(2*n+1);
}
temp=(mo*1.0/de); //更新当前项
}
//最后一项小于阈值的项仍要加进来
total+=temp;
// 保留6位小数输出
cout<<fixed<<setprecision(6)<<total*2.0<<endl;
return 0;
}