1034 有理数四则运算 (20 分)

1034 有理数四则运算 (20 分)

本题要求编写程序,计算 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

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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值