1088 Rational Arithmetic (20 分)

1088 Rational Arithmetic (20 分)

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

AC代码

#include <iostream>
#include <cstdio>
using namespace std;
long int GCD(long int x, long int y);
long int LCM(long int x, long int y);
int main() {
	long int a1, b1, a2, b2, Z1 = 0, Z2 = 0, Sign1 = 1, Sign2 = 1, Mark = 1, Flag = 1;	//Flag在整数部分为零时判断该数的正负
	long int s1 = 1, s2 = 1, s3 = 1, s4 = 1;											//Mark标志原始数是否有零
	scanf("%ld/%ld %ld/%ld", &a1, &b1, &a2, &b2);	//得到两个数
	if (a1 < 0) { a1 = -a1; Sign1 = -1; }
	else if (!a1) Mark = 0;
	if (a2 < 0) { a2 = -a2; Sign2 = -1; }	//正负问题
	else if (!a2) Mark = 0;
	if (Mark) {		//两个原始数都不为零
		long int Tmp1GCD = GCD(a1, b1);		//得到第一个数分子与分母的最大公约数
		a1 /= Tmp1GCD;
		b1 /= Tmp1GCD;		//得到第一个数的最简分数形式
		long int doa1 = a1, dob1 = b1;	//用于实际运算
		if (b1 == 1) { Z1 = a1 * Sign1; a1 = 0; }	//若分母为整数
		else if (a1 > b1) { Z1 = a1 / b1 * Sign1; a1 = a1 % b1; }	//若为假分数
		long int Tmp2GCD = GCD(a2, b2);		//得到第二个数分子与分母的最大公约数
		a2 /= Tmp2GCD;
		b2 /= Tmp2GCD;		//得到第二个数的最简分数形式
		long int doa2 = a2, dob2 = b2;	//用于实际运算
		if (b2 == 1) { Z2 = a2 * Sign2; a2 = 0; }	//若分母为整数
		else if (a2 > b2) { Z2 = a2 / b2 * Sign2; a2 = a2 % b2; }	//若为假分数
		/*-------------------原始两个数化简完毕-------------------*/
		long int retZ, reta, retb;	//最终结果的整数 分子 分母
		/*-------------------开始加法运算-------------------*/
		if ((Sign1 > 0 && Sign2 > 0) || (Sign1 < 0 && Sign2 < 0)) {
			long int Tmpb = LCM(dob1, dob2);	//得到两个分母的最小公倍数
			long int Tmpa = doa1 * (Tmpb / dob1) + doa2 * (Tmpb / dob2);
			long int TmpGCD = GCD(Tmpa, Tmpb);
			reta = Tmpa / TmpGCD;
			retb = Tmpb / TmpGCD;		//得到结果的最简分数形式
			if (retb == 1) { retZ = reta * Sign1; reta = 0; }	//若分母为整数
			else if (reta > retb) { retZ = reta / retb * Sign1; reta = reta % retb; }	//若为假分数
			else { retZ = 0; Flag = (Sign1 > 0) ? 1 : 0; }
		}
		else {	//一个正数 一个负数
			long int Tmpb = LCM(dob1, dob2);	//得到两个分母的最小公倍数
			long int Tmpa = abs(doa1 * (Tmpb / dob1) - doa2 * (Tmpb / dob2));
			long int TmpGCD = GCD(Tmpa, Tmpb);
			reta = Tmpa / TmpGCD;
			retb = Tmpb / TmpGCD;		//得到结果的最简分数形式
			if (retb == 1) { retZ = -reta; reta = 0; }	//若分母为整数
			else if (reta > retb) { retZ = -(reta / retb); reta = reta % retb; }	//若为假分数
			else { retZ = 0; Flag = 0; }
		}
		/*-------------------开始格式输出加法结果-------------------*/
		if (Z1 < 0) {	//整数部分小于零时
			if (a1) printf("(%ld %ld/%ld) + ", Z1, a1, b1);
			else printf("(%ld) + ", Z1);
		}
		else if (Z1 > 0) {	//整数部分大于零时
			if (a1) printf("%ld %ld/%ld + ", Z1, a1, b1);
			else printf("%ld + ", Z1);
		}
		else {
			if (Sign1 > 0) printf("%ld/%ld + ", a1, b1);	//整数部分为零 分数部分一定不为零
			else printf("(%ld/%ld) + ", -a1, b1);
		}
		if (Z2 < 0) {	//整数部分小于零时
			if (a2) printf("(%ld %ld/%ld) = ", Z2, a2, b2);
			else printf("(%ld) = ", Z2);
		}
		else if (Z2 > 0) {	//整数部分大于零时
			if (a2) printf("%ld %ld/%ld = ", Z2, a2, b2);
			else printf("%ld = ", Z2);
		}
		else {
			if (Sign2 > 0) printf("%ld/%ld = ", a2, b2);	//整数部分为零 分数部分一定不为零
			else printf("(%ld/%ld) = ", -a2, b2);
		}
		if (retZ < 0) {	//整数部分小于零时
			if (reta) printf("(%ld %ld/%ld)\n", retZ, reta, retb);
			else printf("(%ld)\n", retZ);
		}
		else if (retZ > 0) {	//整数部分大于零时
			if (reta) printf("%ld %ld/%ld\n", retZ, reta, retb);
			else printf("%ld\n", retZ);
		}
		else {
			if (!reta) printf("0\n");
			else {
				if (Flag) printf("%ld/%ld\n", reta, retb);
				else printf("(-%ld/%ld)\n", reta, retb);
			}
		}	//整数部分为零 分数部分一定不为零
		/*-------------------结束格式输出加法结果-------------------*/
		/*-------------------开始减法运算-------------------*/
		long int Com = 1;
		if ((Sign1 > 0 && Sign2 > 0) || (Sign1 < 0 && Sign2 < 0)) {
			long int Tmpb = LCM(dob1, dob2);	//得到两个分母的最小公倍数
			long int Tmpa = doa1 * (Tmpb / dob1) - doa2 * (Tmpb / dob2);
			if (Tmpa < 0) { Tmpa = -Tmpa; Com = -1; }	//考虑两数相减的正负
			long int TmpGCD = GCD(Tmpa, Tmpb);
			reta = Tmpa / TmpGCD;
			retb = Tmpb / TmpGCD;		//得到结果的最简分数形式
			if (retb == 1) { retZ = reta * Sign1 * Com; reta = 0; }	//若分母为整数
			else if (reta > retb) { retZ = reta / retb * Sign1 * Com; reta = reta % retb; }	//若为假分数
			else {
				retZ = 0;
				if (Sign1 * Com < 0) Flag = 0;
				else Flag = 1;
			}
		}
		else {	//一个正数 一个负数
			long int Tmpb = LCM(dob1, dob2);	//得到两个分母的最小公倍数
			long int Tmpa = doa1 * (Tmpb / dob1) + doa2 * (Tmpb / dob2);
			long int TmpGCD = GCD(Tmpa, Tmpb);
			reta = Tmpa / TmpGCD;
			retb = Tmpb / TmpGCD;		//得到结果的最简分数形式
			if (Sign1 < 0) {Com = -1; retZ = 0; Flag = 0; }	//负数减整数结果为负数
			if (retb == 1) { retZ = reta * Com; reta = 0; }	//若分母为整数
			else if (reta > retb) { retZ = reta / retb * Com; reta = reta % retb; }	//若为假分数
		}
		/*-------------------开始格式输出减法结果-------------------*/
		if (Z1 < 0) {	//整数部分小于零时
			if (a1) printf("(%ld %ld/%ld) - ", Z1, a1, b1);
			else printf("(%ld) - ", Z1);
		}
		else if (Z1 > 0) {	//整数部分大于零时
			if (a1) printf("%ld %ld/%ld - ", Z1, a1, b1);
			else printf("%ld - ", Z1);
		}
		else {
			if (Sign1 > 0) printf("%ld/%ld - ", a1, b1);	//整数部分为零 分数部分一定不为零
			else printf("(%ld/%ld) - ", -a1, b1);
		}
		if (Z2 < 0) {	//整数部分小于零时
			if (a2) printf("(%ld %ld/%ld) = ", Z2, a2, b2);
			else printf("(%ld) = ", Z2);
		}
		else if (Z2 > 0) {	//整数部分大于零时
			if (a2) printf("%ld %ld/%ld = ", Z2, a2, b2);
			else printf("%ld = ", Z2);
		}
		else {
			if (Sign2 > 0) printf("%ld/%ld = ", a2, b2);	//整数部分为零 分数部分一定不为零
			else printf("(%ld/%ld) = ", -a2, b2);
		}
		if (retZ < 0) {	//整数部分小于零时
			if (reta) printf("(%ld %ld/%ld)\n", retZ, reta, retb);
			else printf("(%ld)\n", retZ);
		}
		else if (retZ > 0) {	//整数部分大于零时
			if (reta) printf("%ld %ld/%ld\n", retZ, reta, retb);
			else printf("%ld\n", retZ);
		}
		else {
			if (!reta) printf("0\n");
			else {
				if (Flag) printf("%ld/%ld\n", reta, retb);
				else printf("(-%ld/%ld)\n", reta, retb);
			}
		}//整数部分为零 分数部分一定不为零
		/*-------------------结束格式输出减法结果-------------------*/
		/*-------------------开始乘法运算-------------------*/
		if ((Sign1 > 0 && Sign2 > 0) || (Sign1 < 0 && Sign2 < 0)) {
			long int Tmpa = doa1 * doa2;
			long int Tmpb = dob1 * dob2;
			long int TmpGCD = GCD(Tmpa, Tmpb);
			reta = Tmpa / TmpGCD;
			retb = Tmpb / TmpGCD;		//得到结果的最简分数形式
			if (retb == 1) { retZ = reta; reta = 0; }	//若分母为整数
			else if (reta > retb) { retZ = reta / retb; reta = reta % retb; }	//若为假分数
			else { retZ = 0; Flag = 1; }
		}
		else {	//一个正数 一个负数
			long int Tmpa = doa1 * doa2;
			long int Tmpb = dob1 * dob2;
			long int TmpGCD = GCD(Tmpa, Tmpb);
			reta = Tmpa / TmpGCD;
			retb = Tmpb / TmpGCD;		//得到结果的最简分数形式
			if (retb == 1) { retZ = -reta; reta = 0; }	//若分母为整数
			else if (reta > retb) { retZ = -(reta / retb); reta = reta % retb; }	//若为假分数
			else { retZ = 0; Flag = 0; }
		}
		/*-------------------开始格式输出乘法结果-------------------*/
		if (Z1 < 0) {	//整数部分小于零时
			if (a1) printf("(%ld %ld/%ld) * ", Z1, a1, b1);
			else printf("(%ld) * ", Z1);
		}
		else if (Z1 > 0) {	//整数部分大于零时
			if (a1) printf("%ld %ld/%ld * ", Z1, a1, b1);
			else printf("%ld * ", Z1);
		}
		else {
			if (Sign1 > 0) printf("%ld/%ld * ", a1, b1);	//整数部分为零 分数部分一定不为零
			else printf("(%ld/%ld) * ", -a1, b1);
		}
		if (Z2 < 0) {	//整数部分小于零时
			if (a2) printf("(%ld %ld/%ld) = ", Z2, a2, b2);
			else printf("(%ld) = ", Z2);
		}
		else if (Z2 > 0) {	//整数部分大于零时
			if (a2) printf("%ld %ld/%ld = ", Z2, a2, b2);
			else printf("%ld = ", Z2);
		}
		else {
			if (Sign2 > 0) printf("%ld/%ld = ", a2, b2);	//整数部分为零 分数部分一定不为零
			else printf("(%ld/%ld) = ", -a2, b2);
		}
		if (retZ < 0) {	//整数部分小于零时
			if (reta) printf("(%ld %ld/%ld)\n", retZ, reta, retb);
			else printf("(%ld)\n", retZ);
		}
		else if (retZ > 0) {	//整数部分大于零时
			if (reta) printf("%ld %ld/%ld\n", retZ, reta, retb);
			else printf("%ld\n", retZ);
		}
		else {
			if (Flag) printf("%ld/%ld\n", reta, retb);
			else printf("(-%ld/%ld)\n", reta, retb);
		}	//整数部分为零 分数部分一定不为零
		/*-------------------结束格式输出乘法结果-------------------*/
		/*-------------------开始除法运算-------------------*/
		if ((Sign1 > 0 && Sign2 > 0) || (Sign1 < 0 && Sign2 < 0)) {
			long int Tmpa = doa1 * dob2;	//得到分子
			long int Tmpb = dob1 * doa2;	//得到分母
			long int TmpGCD = GCD(Tmpa, Tmpb);
			reta = Tmpa / TmpGCD;
			retb = Tmpb / TmpGCD;		//得到结果的最简分数形式
			if (retb == 1) { retZ = reta; reta = 0; }	//若分母为整数
			else if (reta > retb) { retZ = reta / retb; reta = reta % retb; }	//若为假分数
			else { retZ = 0; Flag = 1; }
		}
		else {	//一个正数 一个负数
			long int Tmpa = doa1 * dob2;	//得到分子
			long int Tmpb = dob1 * doa2;	//得到分母
			long int TmpGCD = GCD(Tmpa, Tmpb);
			reta = Tmpa / TmpGCD;
			retb = Tmpb / TmpGCD;		//得到结果的最简分数形式
			if (retb == 1) { retZ = -reta; reta = 0; }	//若分母为整数
			else if (reta > retb) { retZ = -(reta / retb); reta = reta % retb; }	//若为假分数
			else { retZ = 0; Flag = 0; }
		}
		/*-------------------开始格式输出除法结果-------------------*/
		if (Z1 < 0) {	//整数部分小于零时
			if (a1) printf("(%ld %ld/%ld) / ", Z1, a1, b1);
			else printf("(%ld) / ", Z1);
		}
		else if (Z1 > 0) {	//整数部分大于零时
			if (a1) printf("%ld %ld/%ld / ", Z1, a1, b1);
			else printf("%ld / ", Z1);
		}
		else {
			if (Sign1 > 0) printf("%ld/%ld / ", a1, b1);	//整数部分为零 分数部分一定不为零
			else printf("(%ld/%ld) / ", -a1, b1);
		}
		if (Z2 < 0) {	//整数部分小于零时
			if (a2) printf("(%ld %ld/%ld) = ", Z2, a2, b2);
			else printf("(%ld) = ", Z2);
		}
		else if (Z2 > 0) {	//整数部分大于零时
			if (a2) printf("%ld %ld/%ld = ", Z2, a2, b2);
			else printf("%ld = ", Z2);
		}
		else {
			if (Sign2 > 0) printf("%ld/%ld = ", a2, b2);	//整数部分为零 分数部分一定不为零
			else printf("(%ld/%ld) = ", -a2, b2);
		}
		if (retZ < 0) {	//整数部分小于零时
			if (reta) printf("(%ld %ld/%ld)\n", retZ, reta, retb);
			else printf("(%ld)\n", retZ);
		}
		else if (retZ > 0) {	//整数部分大于零时
			if (reta) printf("%ld %ld/%ld\n", retZ, reta, retb);
			else printf("%ld\n", retZ);
		}
		else {
			if (Flag) printf("%ld/%ld\n", reta, retb);
			else printf("(-%ld/%ld)\n", reta, retb);
		}//整数部分为零 分数部分一定不为零
		/*-------------------结束格式输出除法结果-------------------*/
	}
	else {	//两个原始数至少有一个为零
		if (a1 && !a2) {	//第二个数为零
			long int Tmp1GCD = GCD(a1, b1);		//得到第一个数分子与分母的最大公约数
			a1 /= Tmp1GCD;
			b1 /= Tmp1GCD;		//得到第一个数的最简分数形式
			long int doa1 = a1, dob1 = b1;	//用于实际运算
			if (b1 == 1) { Z1 = a1 * Sign1; a1 = 0; }	//若分母为整数
			else if (a1 > b1) { Z1 = a1 / b1 * Sign1; a1 = a1 % b1; }	//若为假分数
			if (Z1 < 0) {	//整数部分小于零时
				if (a1) {
					printf("(%ld %ld/%ld) + 0 = (%ld %ld/%ld)\n", Z1, a1, b1, Z1, a1, b1);
					printf("(%ld %ld/%ld) - 0 = (%ld %ld/%ld)\n", Z1, a1, b1, Z1, a1, b1);
					printf("(%ld %ld/%ld) * 0 = 0\n", Z1, a1, b1); s3 = 0;
					printf("(%ld %ld/%ld) / 0 = Inf\n", Z1, a1, b1); s4 = 0;
				}
				else {
					printf("(%ld) + 0 = (%ld)\n", Z1, Z1); s1 = 0;
					printf("(%ld) - 0 = (%ld)\n", Z1, Z1); s2 = 0;
					printf("(%ld) * 0 = 0\n", Z1); s3 = 0;
					printf("(%ld) / 0 = Inf\n", Z1); s4 = 0;
				}
			}
			else if (Z1 > 0) {	//整数部分大于零时
				if (a1) {
					printf("%ld %ld/%ld + 0 = %ld %ld/%ld\n", Z1, a1, b1, Z1, a1, b1);
					printf("%ld %ld/%ld - 0 = %ld %ld/%ld\n", Z1, a1, b1, Z1, a1, b1);
					printf("%ld %ld/%ld * 0 = 0\n", Z1, a1, b1);
					printf("%ld %ld/%ld / 0 = Inf\n", Z1, a1, b1);
				}
				else {
					printf("%ld + 0 = %ld\n", Z1, Z1);
					printf("%ld - 0 = %ld\n", Z1, Z1);
					printf("%ld * 0 = 0\n", Z1);
					printf("%ld / 0 = Inf\n", Z1);
				}
			}
			else {
				printf("%ld/%ld + 0 = %ld/%ld\n", a1, b1, a1, b1);	//整数部分为零 分数部分一定不为零
				printf("%ld/%ld - 0 = %ld/%ld\n", a1, b1, a1, b1);	//整数部分为零 分数部分一定不为零
				printf("%ld/%ld * 0 = 0\n", a1, b1);	//整数部分为零 分数部分一定不为零
				printf("%ld/%ld / 0 = Inf\n", a1, b1);	//整数部分为零 分数部分一定不为零
			}
		}
		else if (!a1 && a2) {	//第一个数为零
			long int Tmp2GCD = GCD(a2, b2);		//得到第二个数分子与分母的最大公约数
			a2 /= Tmp2GCD;
			b2 /= Tmp2GCD;		//得到第二个数的最简分数形式
			long int doa2 = a2, dob2 = b2;	//用于实际运算
			if (b2 == 1) { Z2 = a2 * Sign2; a2 = 0; }	//若分母为整数
			else if (a2 > b2) { Z2 = a2 / b2 * Sign2; a2 = a2 % b2; }	//若为假分数
			if (Z2 < 0) {	//整数部分小于零时
				if (a2) {
					printf("0 + (%ld %ld/%ld) = (%ld %ld/%ld)\n", Z2, a2, b2, Z2, a2, b2);
					printf("0 - (%ld %ld/%ld) = %ld %ld/%ld\n", Z2, a2, b2, -Z2, a2, b2);
					printf("0 * (%ld %ld/%ld) = 0\n", Z2, a2, b2);
					printf("0 / (%ld %ld/%ld) = 0\n", Z2, a2, b2);
				}
				else {
					printf("0 + (%ld) = (%ld)\n", Z2, Z2);
					printf("0 - (%ld) = %ld\n", Z2, -Z2);
					printf("0 * (%ld) = 0\n", Z2);
					printf("0 / (%ld) = 0\n", Z2);
				}
			}
			else if (Z2 > 0) {	//整数部分大于零时
				if (a2) {
					printf("0 + %ld %ld/%ld = %ld %ld/%ld\n", Z2, a2, b2, Z2, a2, b2);
					printf("0 - %ld %ld/%ld = (%ld %ld/%ld\n)", Z2, a2, b2, -Z2, a2, b2);
					printf("0 * %ld %ld/%ld = 0\n", Z2, a2, b2);
					printf("0 / %ld %ld/%ld = 0\n", Z2, a2, b2);
				}
				else {
					printf("0 + %ld = %ld\n", Z2, Z2);
					printf("0 - %ld = (%ld)\n", Z2, -Z2);
					printf("0 * %ld = 0\n", Z2);
					printf("0 / %ld = 0\n", Z2);
				}
			}
			else {
				printf("0 + %ld/%ld = %ld/%ld\n", a2, b2, a2, b2);	//整数部分为零 分数部分一定不为零
				printf("0 - %ld/%ld = (-%ld/%ld)\n", a2, b2, a2, b2);	//整数部分为零 分数部分一定不为零
				printf("0 * %ld/%ld = 0\n", a2, b2);	//整数部分为零 分数部分一定不为零
				printf("0 / %ld/%ld = 0\n", a2, b2);	//整数部分为零 分数部分一定不为零
			}
		}
		else {
			printf("0 + 0 = 0\n");	//两个数都是零
			printf("0 - 0 = 0\n");	//两个数都是零
			printf("0 * 0 = 0\n");	//两个数都是零
			printf("0 / 0 = Inf\n");	//两个数都是零
		}
	}
	return 0;
}
long int GCD(long int x, long int y) {
	return (!y) ? x : GCD(y, x % y);
}
long int LCM(long int x, long int y) {
	return x * y / GCD(x, y);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值