1081 Rational Sum (20分) 思路分析 测试点分析(解决你的测试点过不了)

文章目录

  • 题目
  • 题目大意
  • 思路分析
  • 测试点分析
  • 代码

题目

Given N rational numbers in the form numerator/denominator, you are supposed to calculate their sum.
Input Specification:

Each input file contains one test case. Each case starts with a positive integer N (≤100), followed in the next line N rational numbers a1/b1 a2/b2 … where all the numerators and denominators are in the range of long int. If there is a negative number, then the sign must appear in front of the numerator.
Output Specification:

For each test case, output the sum in the simplest form integer numerator/denominator where integer is the integer part of the sum, numerator < denominator, and the numerator and the denominator have no common factor. You must output only the fractional part if the integer part is 0.
Sample Input 1:

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

Sample Output 1:

3 1/3

Sample Input 2:

2
4/3 2/3

Sample Output 2:

2

Sample Input 3:

3
1/3 -1/6 1/8

Sample Output 3:

7/24

题目大意

给定分子/分母形式的N个有理数,你应该计算它们的和。
输入规格:

每个输入文件包含一个测试用例。每种情况都以一个正整数N (≤100)开始,然后是下一行N个有理数a1/b1 a2/b2…所有的分子和分母都在长整数的范围内。如果有负数,那么符号必须出现在分子前面。
输出规格:

对于每个测试用例,以整数分子/分母的最简单形式输出和,其中整数是和的整数部分,分子<分母,分子和分母没有公共因子。如果整数部分为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

思路分析

这道题是求若干个有理数的和,其中涉及到分数的加法。
首先我们回想一下分数的加法:1081 Rational Sum (20分) 思路分析 测试点分析(解决你的测试点过不了)_第1张图片所以若干个分数之和可以按照此思路一样的加和。
其次现在的到的结果可能是一个假分数,此时我们需要进行约分。这时候必然涉及到求公因数。
求公因数我们通常采用辗转相除法实现:
辗转相除法,又名欧几里得算法 ,其原理其实是基于这个定理:gcd(a,b)=gcd(b,a%b)
递归实现(C++):

long long gcd(long long a, long long b)
{
     
	return b == 0 ? abs(a) : gcd(b, a%b);
}

最后考虑特殊情况,比如求出的分子分母为0的时候,再比如-1/2 2/4的情况

测试点分析

(1) 题中,所有的分子分母都是long int 型,但是相乘可能出现超过long int的情况,所以将其改为(long long).
(2)测试点4出现浮点错误,开始我想了很久,没想明白哪里出现/0,%0的情况(浮点错误一般是出现了/0,%0的情况)后来我发现如果求出的公因数gcdvalue为0,sum1/gcdvalue,sum2/gcdvalue就会出现浮点错误。所以需要特殊判断。

代码

#include
#include
using namespace std;
long long gcd(long long a, long long b)
{
     
	return b == 0 ? abs(a) : gcd(b, a%b);
}
int main()
{
     
	long long n, sum1 = 1,a,b,sum2=1,flag=0;
	scanf("%lld", &n);
	scanf("%lld/%lld", &a, &b);
	sum1 = a;
	sum2 = b;
	for (int i = 1; i < n; i++)
	{
     
		scanf("%lld/%lld", &a, &b);
		sum1 = sum1 * b + sum2 * a;
		sum2 *= b;
	}
	long long gcdvalue = gcd(sum1, sum2);
	if (gcdvalue == 0)
	{
     
		printf("0");
		return 0;
	}
	sum1 = sum1 / gcdvalue;
	sum2 = sum2 / gcdvalue;
	if (sum1 < 0) printf("-");
	if (abs(sum1) / abs(sum2))
	{
     
		printf("%lld", abs(sum1) / abs(sum2));
		flag++;
	}
	if (abs(sum1) % abs(sum2))
	{
     
		if (flag) printf(" ");
		printf("%lld/%lld", abs(sum1) % abs(sum2), abs(sum2));
	}

	return 0;
}

你可能感兴趣的:(PAT,A)