L1-009 N个数求和(完整代码)

作者 陈越

单位 浙江大学

本题的要求很简单,就是求N个数字的和。麻烦的是,这些数字是以有理数分子/分母的形式给出的,你输出的和也必须是有理数的形式。

输入格式:

输入第一行给出一个正整数N(≤100)。随后一行按格式a1/b1 a2/b2 ...给出N个有理数。题目保证所有分子和分母都在长整型范围内。另外,负数的符号一定出现在分子前面。

输出格式:

输出上述数字和的最简形式 —— 即将结果写成整数部分 分数部分,其中分数部分写成分子/分母,要求分子小于分母,且它们没有公因子。如果结果的整数部分为0,则只输出分数部分。

输入样例1:

5
2/5 4/15 1/30 -2/60 8/3

输出样例1:

3 1/3

输入样例2:

2
4/3 2/3

输出样例2:

2

输入样例3:

3
1/3 -1/6 1/8

输出样例3:

7/24

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

 思路:首先题目涉及分子分母的通分和化简,需要会写求最大公因数和最小公倍数的函数

#define  ll long long//更直观一些
//求最大公约数
ll gcd(ll a, ll b)
{
	return b == 0 ? a : gcd(b, a % b);
}

// 求最小公倍数  
ll lcm(ll a, ll b) 
{
	return a*b / gcd(a, b);
}

然后接受输入,把分子和分母分别存起来 ,这里负数可以正确地被存在分子数组中

int n;
	cin >> n;
	vector<ll>fenzi;
	vector<ll>fenmu;
	for (int i = 0; i < n; i++)
	{
		ll x, y;
		char a;
		cin >> x >> a >> y;
		fenzi.push_back(x);
		fenmu.push_back(y);

既然题目最后要求的是求输入所有分数的和,并且要求最简形式,那么我们肯定要把这些分数都加起来?怎么加起来呢? 我们不妨回想一下在数学中把分数加起来的思路,很简单!就是通分,那么我们就需要遍历fenmu数组,找出分母们的最小公倍数

ll yLast = 1; // 通分后的分母  
//找到所有分母的最小公倍数
for (int i = 0; i < n; i++) 
{
	ll y = fenmu[i];
	ll a = lcm(yLast, y); // 计算当前分母和已通分分母的最小公倍数  
	yLast = a; // 更新通分后的分母  
}

分母们的最小公倍数找到之后,我们就可以更新通分后的分子

 按照如此的数学思路,用代码实现的思路就是,遍历分子数组,计算通分后的分子,然后开一个pair类型的数组,将通分后的数存进去,

vector<pair<ll, ll>> num; // 存储通分后的分子和分母  
	for (int i = 0; i < n; i++)
	{
		ll x = fenzi[i];
		ll y = fenmu[i];
		num.push_back(make_pair(x * (yLast / y), yLast )); // 通分后的分子和分母  
	}

	// 计算通分后所有分子的和  
	ll xLast = 0;
	for (auto p : num) 
	{
		xLast += p.first;
	}

此时我们已经找到了通分后所有分子的和xLast和分母的最小公倍数yLast,只需要对这两个数化简一下就行,即除以它们的最大公因数;

// 约简分数  
ll gcdVal = gcd(xLast, yLast);
xLast /= gcdVal;
yLast /= gcdVal;

最后输出,注意题目要求,此处思路在代码注释中详细讲解

// 输出结果  
if (xLast == 0) //相加后分子为0
{
	cout << "0";
}
else if (xLast % yLast == 0) // 如果分子是分母的整数倍,则只输出整数部分
{   
	cout << xLast / yLast;
}
else if(xLast/yLast)// 否则输出整数部分和分数部分,整数部分不为0输出整数部分,即该分数大于1
{ //类似于数学中的带分数
	cout << xLast / yLast << " " << (xLast% yLast) << "/" << yLast;
}
else//整数部分为0,则不输出整数部分,即该分数小于1
{
	cout << (xLast% yLast) << "/" << yLast;
}

 完整代码:

#include <vector>
#include <iostream>
#define  ll long long
using namespace std;

//求最大公约数
ll gcd(ll a, ll b)
{
	return b == 0 ? a : gcd(b, a % b);
}

// 求最小公倍数  
ll lcm(ll a, ll b) 
{
	return a*b / gcd(a, b);
}

int main()
{
	//接受输入,将分子和分母存在数组中
	int n;
	cin >> n;
	vector<ll>fenzi;
	vector<ll>fenmu;
	for (int i = 0; i < n; i++)
	{
		ll x, y;
		char a;
		cin >> x >> a >> y;
		fenzi.push_back(x);
		fenmu.push_back(y);
	}


	ll yLast = 1; // 通分后的分母  
	//找到所有分母的最小公倍数
	for (int i = 0; i < n; i++) 
	{
		ll y = fenmu[i];
		ll a = lcm(yLast, y); // 计算当前分母和已通分分母的最小公倍数  
		yLast = a; // 更新通分后的分母  
	}

	vector<pair<ll, ll>> num; // 存储通分后的分子和分母  
	for (int i = 0; i < n; i++)
	{
		ll x = fenzi[i];
		ll y = fenmu[i];
		num.push_back(make_pair(x * (yLast / y), yLast )); // 通分后的分子和分母  
	}

	// 计算通分后所有分子的和  
	ll xLast = 0;
	for (auto p : num) 
	{
		xLast += p.first;
	}

	// 约简分数  
	ll gcdVal = gcd(xLast, yLast);
	xLast /= gcdVal;
	yLast /= gcdVal;

	// 输出结果  
	if (xLast == 0) //相加后分子为0
	{
		cout << "0";
	}
	else if (xLast % yLast == 0) // 如果分子是分母的整数倍,则只输出整数部分
	{   
		cout << xLast / yLast;
	}
	else if(xLast/yLast)// 否则输出整数部分和分数部分,整数部分不为0输出整数部分,即该分数大于1
	{ //类似于数学中的带分数
		cout << xLast / yLast << " " << (xLast% yLast) << "/" << yLast;
	}
	else//整数部分为0,则不输出整数部分,即该分数小于1
	{
		cout << (xLast% yLast) << "/" << yLast;
	}

	return 0;

}

相关推荐

  1. PTA L1-009 N个数求和(C++)

    2024-04-12 02:20:02       40 阅读
  2. L1-039 古风排版

    2024-04-12 02:20:02       44 阅读
  3. nn相加求和,从1~n,金币】

    2024-04-12 02:20:02       33 阅读
  4. L1-039 古风排版(C++)

    2024-04-12 02:20:02       41 阅读
  5. L1-019 谁先倒python

    2024-04-12 02:20:02       32 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-12 02:20:02       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-12 02:20:02       106 阅读
  3. 在Django里面运行非项目文件

    2024-04-12 02:20:02       87 阅读
  4. Python语言-面向对象

    2024-04-12 02:20:02       96 阅读

热门阅读

  1. 程序员面试经典——01.01. 判定字符是否唯一

    2024-04-12 02:20:02       36 阅读
  2. 设计基于锁的并发数据结构

    2024-04-12 02:20:02       39 阅读
  3. python——循环语句

    2024-04-12 02:20:02       37 阅读
  4. 蓝桥杯备考随手记: 动态规划

    2024-04-12 02:20:02       39 阅读
  5. 生成式伪造语音安全问题与解决方案(上)

    2024-04-12 02:20:02       41 阅读
  6. redis缓存实现分布式锁原理及注意事项(附代码)

    2024-04-12 02:20:02       35 阅读