PTA|基础编程题目集|7-15

解题#

循环判断当前项是否大于给定阈值,大于就将当前项累加到结果中,否则继续。

如何计算当前项?

  • 分子、分母直接简单累乘后相除 不符合题目要求,会超出范围

  • 分子分母约分化简后再相除,如何化简?

    • 观察通项:

      n!357...(2n+1)

      分子是n!,分母是奇数累乘。等价表示如下:

      12345...n357...(2n+1)

      分子与分母之间有共同的约数(奇数):3,5,7....。分子分母化简后就形如:

    • 化简通项

    n为偶数,分母小于n的因子都被约掉了

    246...n(n+1)...(2n+1)

    n为奇数, 分母小于等于n的因子被约掉了

    246...(n1)(n+2)...(2n+1)

    • 相除计算

      根据化简后的通项公式,可以求出每一项的值。但是对于这样的问题,后一项与前一项之间存在一定的递进关系,各自单独求出每一项,势必存在重复的计算,不够明智,很自然的想法是期望在上一项的基础上,进行少量的运算即可得出当前项的结果。

      类似我们求解1!+2!+3!+...+n!

是否可行呢,我们先看具体的项数(n=4,5,6)情况。

n=4

24579

n=5

247911

n=6

246791113

观察可知,分子变化相对简单——因子只增加,而分母的因子存在增加和减少的情况。

若n为偶数,分母增加的因子是(2*n+1),分子增加因子n

若n为奇数,分母增加的因子是2*n+1,减少的因子是n,分子不变。

接下来通过具体的代码去实现。

关键点#

每一项的分子与分母类型为 long long int,需要将分子与分母化简后再计算,不能直接各自求积相除,否则报错。

参考代码#

copy#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;
}
posted @   Devinwon  阅读(230)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示
主题色彩