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;
}
原文地址:https://www.cnblogs.com/reaptem/p/14006681.html