1088 Rational Arithmetic
For two rational numbers, your task is to implement the basic arithmetics, that is, to calculate their sum, difference, product and quotient.
Input Specification:
Each input file contains one test case, which gives in one line the two rational numbers in the format a1/b1 a2/b2
. The numerators and the denominators are all in the range of long int. If there is a negative sign, it must appear only in front of the numerator. The denominators are guaranteed to be non-zero numbers.
Output Specification:
For each test case, print in 4 lines the sum, difference, product and quotient of the two rational numbers, respectively. The format of each line is number1 operator number2 = result
. Notice that all the rational numbers must be in their simplest form k a/b
, where k
is the integer part, and a/b
is the simplest fraction part. If the number is negative, it must be included in a pair of parentheses. If the denominator in the division is zero, output Inf
as the result. It is guaranteed that all the output integers are in the range of long int.
Sample Input 1:
2/3 -4/2
Sample Output 1:
2/3 + (-2) = (-1 1/3)
2/3 - (-2) = 2 2/3
2/3 * (-2) = (-1 1/3)
2/3 / (-2) = (-1/3)
Sample Input 2:
5/3 0/6
Sample Output 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
题意:
给出两个用分数表示的数字,分别输出这两个数字的+,-,* ,/
思路:
这种题不难,但是很麻烦,我的思路是先将两个原始数字通分,然后计算+, -, *, /。然后将计算的结果化成带分数,分子分母在进行约分。
Code:
#include<iostream> #include<string> using namespace std; struct Num { int sign = 1; long long integer; long long numerators; long long denominators; long long originNumer; }; long long _gcd(long long a, long long b) { if (a % b == 0) return b; else return _gcd(b, a%b); } void coutAns(long long numerators, long long denominators) { long long suminteger = numerators / denominators; long long sumNumer = numerators % denominators; long long gcd = _gcd(sumNumer, denominators); if (suminteger != 0) cout << suminteger; if (suminteger != 0 && sumNumer != 0) cout << " "; if (sumNumer != 0) cout << sumNumer/gcd << "/" << denominators/gcd; } void print(Num n) { if (n.sign == -1) cout << "(-"; if (n.integer != 0) cout << n.integer; if (n.integer != 0 && n.numerators != 0) cout << " "; if (n.numerators != 0) cout << n.numerators << "/" << n.denominators; if (n.sign == -1) cout << ")"; if (n.integer == 0 && n.numerators == 0) cout << 0; } void sum(Num n1, Num n2) { print(n1); cout << " + "; print(n2); cout << " = "; long long sumNumer = n1.sign * n1.originNumer * n2.denominators + n2.sign * n2.originNumer * n1.denominators; long long sumDeno = n1.denominators * n2.denominators; if (sumNumer == 0) cout << 0 << endl; else if (sumNumer < 0) { cout << "(-"; sumNumer *= -1; coutAns(sumNumer, sumDeno); cout << ")" << endl; } else { coutAns(sumNumer, sumDeno); cout << endl; } } void difference(Num n1, Num n2) { print(n1); cout << " - "; print(n2); cout << " = "; long long sumNumer = n1.sign * n1.originNumer * n2.denominators - n2.sign * n2.originNumer * n1.denominators; long long sumDeno = n1.denominators * n2.denominators; if (sumNumer == 0) cout << 0 << endl; else if (sumNumer < 0) { cout << "(-"; sumNumer *= -1; coutAns(sumNumer, sumDeno); cout << ")" << endl; } else { coutAns(sumNumer, sumDeno); cout << endl; } } void product(Num n1, Num n2) { print(n1); cout << " * "; print(n2); cout << " = "; long long sumNumer = n1.originNumer * n2.originNumer; long long sumDeno = n1.denominators * n2.denominators; if (sumNumer == 0) cout << 0 << endl; else if (n1.sign*n2.sign < 0) { cout << "(-"; coutAns(sumNumer, sumDeno); cout << ")" << endl; } else { coutAns(sumNumer, sumDeno); cout << endl; } } void quotient(Num n1, Num n2) { print(n1); cout << " / "; print(n2); cout << " = "; if (n2.originNumer == 0) cout << "Inf" << endl; else { long long sumNumer = n1.originNumer * n2.denominators; long long sumDeno = n1.denominators * n2.originNumer; if (sumNumer == 0) cout << 0 << endl; else if (n1.sign*n2.sign < 0) { cout << "(-"; coutAns(sumNumer, sumDeno); cout << ")" << endl; } else { coutAns(sumNumer, sumDeno); cout << endl; } } } Num parsing(string s) { Num a; long long i = 0; long long numerators, denominators, gcd; string s1, s2; if (s[0] == '-') { i = 1; a.sign = -1; } for (; i < s.length(); ++i) { if (s[i] == '/') break; s1 += s[i]; } ++i; for (; i < s.length(); ++i) { s2 += s[i]; } numerators = stoi(s1); denominators = stoi(s2); gcd = _gcd(numerators, denominators); a.originNumer = numerators / gcd; a.denominators = denominators / gcd; a.integer = numerators / denominators; a.numerators = a.originNumer % a.denominators; return a; } int main() { string str; getline(cin, str); long long pos = str.find(' '); string num1, num2; num1 = str.substr(0, pos); num2 = str.substr(pos+1); Num n1 = parsing(num1); Num n2 = parsing(num2); sum(n1, n2); difference(n1, n2); product(n1, n2); quotient(n1, n2); return 0; }
经过我的不断努力终于把全部的测试点都通过了,有几点需要注意的:
1. 因为题目中说了所有的数据都不会超过long int,所以在初始化数据类型的时候要选用long long类型的。
2. 输入的时候分子,分母,能约分就约分,如果不约分的话,乘的时候可能会溢出。这一点参考了(https://www.liuchuo.net/archives/1906)
3. 还有就是在构建结构体的时候,对于记录数字正负号的tag要赋初值1,否则的话会报错。如果不付出只的话,int类型的数字是一个随机数。
2020-07-22 22:17:36
今天模拟赛的时候又碰到了这道题,写了一个多小时,最后还是没写出来,最关键的是影响了后面做题的心情,得不偿失,真的很不值。正式考试的时候如果再碰到这样的题的话,做20min写不出来的话,就先放下去写其它的去吧,如果最后还有时间可以考虑再做。
看了一下别人的代码,把每一个数字的分子和分母直接传入到一个函数里面,然后编写一个函数来处理这样的一个分数,这样写可以使编写的函数较为简单。
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 long long a, b, c, d; 6 7 long long gcd(long long t1, long long t2) { 8 return t2 == 0 ? t1 : gcd(t2, t1 % t2); 9 } 10 11 void func(long long m, long long n) { 12 if (m * n == 0) { 13 printf("%s", n == 0 ? "Inf" : "0"); 14 return; 15 } 16 bool flag = ((m < 0 && n > 0) || (m > 0 && n < 0)); 17 m = abs(m); 18 n = abs(n); 19 long long x = m / n; 20 printf("%s", flag ? "(-" : ""); 21 if (x != 0) printf("%lld", x); 22 if (m % n == 0) { 23 if (flag) printf(")"); 24 return; 25 } 26 if (x != 0) printf(" "); 27 m = m - x * n; 28 long long t = gcd(m, n); 29 m = m / t; 30 n = n / t; 31 printf("%lld/%lld%s", m, n, flag ? ")" : ""); 32 } 33 34 int main() { 35 scanf("%lld/%lld %lld/%lld", &a, &b, &c, &d); 36 func(a, b); 37 printf(" + "); 38 func(c, d); 39 printf(" = "); 40 func(a * d + b * c, b * d); 41 printf("\n"); 42 func(a, b); 43 printf(" - "); 44 func(c, d); 45 printf(" = "); 46 func(a * d - b * c, b * d); 47 printf("\n"); 48 func(a, b); 49 printf(" * "); 50 func(c, d); 51 printf(" = "); 52 func(a * c, b * d); 53 printf("\n"); 54 func(a, b); 55 printf(" / "); 56 func(c, d); 57 printf(" = "); 58 func(a * d, b * c); 59 60 return 0; 61 }
这两天得调整一下时间,不要到考试的时候晕晕乎乎的。