PTA 乙级——1034 有理数四则运算 C++实现

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_45677518/article/details/102590035

题目 有理数四则运算

本题要求编写程序,计算 2 个有理数的和、差、积、商。

输入格式:

输入在一行中按照 a1/b1 a2/b2 的格式给出两个分数形式的有理数,其中分子和分母全是整型范围内的整数,负号只可能出现在分子前,分母不为 0。

输出格式:

分别在 4 行中按照 有理数1 运算符 有理数2 = 结果 的格式顺序输出 2 个有理数的和、差、积、商。注意输出的每个有理数必须是该有理数的最简形式 k a/b,其中 k 是整数部分,a/b 是最简分数部分;若为负数,则须加括号;若除法分母为 0,则输出 Inf。题目保证正确的输出中没有超过整型范围的整数。

输入样例 1:

2/3 -4/2

输出样例 1:

2/3 + (-2) = (-1 1/3)

2/3 - (-2) = 2 2/3

2/3 * (-2) = (-1 1/3)

2/3 / (-2) = (-1/3)

输入样例 2:

5/3 0/6

输出样例 2:

1 2/3 + 0 = 1 2/3

1 2/3 - 0 = 1 2/3

1 2/3 * 0 = 0

1 2/3 / 0 = Inf

这个题真真实实卡了一下午,先是一直报浮点错误,然后测试点3又卡着说答案错误,写一下下午踩的坑。

首先这个题的思路还是很简单的,我用的通分求的加减乘除,加个循环后面switch一下也可,8过需要注意的是输出的不仅是k a/b的形式,而且a/b还必须是最简形式,所以需要求出最大公约数,用辗转相除求一下就行(普通循环会有超时)。

然后坑就出现了,题目上说了一句:

“题目保证正确的输出中没有超过整型范围的整数”

然而,这并不能保证在计算过程中不会有超出整型范围的整数。

所以,通分的时候一定要注意加上long long才行,不然就会答案错误。

以及,最后发现其实可以直接定义输入都是long long类型的,就不需要后面再打括号写了,就是得这样输入,完整的代码在后面懒得改了:

	long long a1, b1, a2, b2;
	scanf("%lld/%lld %lld/%lld", &a1, &b1, &a2, &b2);

然后就是浮点错误,搜了一下别人的有说PTA用abs会报浮点错误,我用了没有。

浮点错误主要是因为分母有0:

比如10和0求得的最大公约数如果为0,再给他来一个约分就肯定会报错,所以算的时候要么保证最大公约数不为0要么就为0的话特殊处理一下,就能保证k a/b(我用的fraction函数)里面b的值约分之后仍然不为0。

再然后就是除法的时候需要考虑一下,如果a2为0(题目规定b1、b2不为0)的话输出Inf。

最后需要注意一下负号和括号的处理,基本上就没有问题了。

大概就这些,愿这个世界没有bug

在这里插入图片描述

代码

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>

using namespace std;

//  输出最大公约数
long long gcd(long long a, long long b)
{
	if (a < b)
		a, b = b, a;   //   a为大数,b为小数
	while (a%b != 0)   //   辗转相除
	{
		long long temp = a%b;
		a = b;
		b = temp;
	}
	return b;
}

//  输出k a/b格式
void fraction(long long a,long long b)
{
	if (a<0|| b<0)
		cout << "(-";
	if (a%b == 0)
	{
		cout << abs(a / b);
	}
	else
	{
		if (a / b != 0)
			cout << abs(a / b) << " ";
		cout << abs(a%b) << "/" << abs(b);
	}
	if (a<0||b<0)
		cout << ")";
}

int main()
{
	int a1, b1, a2, b2;
	scanf("%d/%d %d/%d", &a1, &b1, &a2, &b2);

	int gcd1 = gcd(a1, b1);
	int gcd2 = gcd(a2, b2);
	int g;
	//  加法
	fraction(a1 / gcd1, b1 / gcd1);
	cout << " + ";
	fraction(a2 / gcd2, b2 / gcd2);
	cout << " = ";
	long long num = (long long)a1*b2 + (long long)a2*b1;
	long long den = (long long)b1*b2;
	g = gcd(num,den);
	fraction(num / g, den / g);
	cout << "\n";

	//  减法
	fraction(a1 / gcd1, b1 / gcd1);
	cout << " - ";
	fraction(a2 / gcd2, b2 / gcd2);
	cout << " = ";
	num = (long long)a1*b2 - (long long)a2*b1;
	den = (long long)b1*b2;
	g = gcd(num, den);
	fraction(num / g, den / g);
	cout << "\n";

	//  乘法
	fraction(a1 / gcd1, b1 / gcd1);
	cout << " * ";
	fraction(a2 / gcd2, b2 / gcd2);
	cout << " = ";
	num = (long long)a1*a2;
	den = (long long)b1*b2;
	g = gcd(num, den);
	fraction(num / g, den / g);
	cout << "\n";

	//  除法
	fraction(a1 / gcd1, b1 / gcd1);
	cout << " / ";
	fraction(a2 / gcd2, b2 / gcd2);
	cout << " = ";
	if (a2 == 0)
		cout << "Inf";
	else
	{
		num = (long long)a1*b2;
		den = (long long)b1*a2;
		g = gcd(num, den);
		fraction(num / g, den / g);

	}

}

猜你喜欢

转载自blog.csdn.net/qq_45677518/article/details/102590035