本题要求编写程序,计算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 = 01 2/3 / 0 = Inf
写了很久,主要是要把不同的情况都考虑进去,另外很坑的是题目虽然说保证正确的输出中没有超过整型范围的整数,但是用int出现错误,
网上一查才了解在计算过程中2个int型相乘会超出范围,就干脆全部用long long了
#include <stdio.h> #include <math.h> typedef long long ll; ll gcd(ll a,ll b); ll output(ll a1,ll b1); ll judge(ll *a,ll *b,ll *flag); int main() { char a[4] = "+-*/"; ll a1,b1,a2,b2; ll i; ll dem,quo1,quo2; ll b[4]; scanf("%lld/%lld %lld/%lld",&a1,&b1,&a2,&b2); dem = b1*b2;//和差积的分母 b[0] = a1*b2 + a2*b1;//和的分子 b[1] = a1*b2 - a2*b1;//差的分子 b[2] = a1*a2;//积的分子 if(a2!=0) { quo1 = a1*b2;//商的分子 quo2 = a2*b1;//商的分母 if(quo2<0) { quo2 *= -1; quo1 *= -1; } } for(i=0;i<4;i++) { output(a1,b1); printf(" %c ",a[i]); output(a2,b2); printf(" = "); i==3 ? (a2==0 ? printf("Inf") : output(quo1,quo2)): output(b[i],dem);//除法特殊情况 printf("\n"); } return 0; } ll gcd(ll a,ll b) { ll temp; if(a<b) { temp = a; a = b; b = temp; } return b==0 ? a : gcd(b,a%b); } ll output(ll a1,ll b1) { ll flag = 0; ll minusflag; minusflag = judge(&a1,&b1,&flag); if(b1==1)//分母为1时 { printf("%s%lld%s",minusflag==1 ? "(-" : "",a1,minusflag==1 ? ")" : ""); } else{ if(flag==0)//分子不大于分母时 { printf("%s%lld/%lld%s",minusflag==1 ? "(-" : "",a1,b1,minusflag==1 ? ")" : ""); } else{//分子大于分母时 printf("%s%lld %lld/%lld%s",minusflag==1 ? "(-" : "",flag,a1,b1,minusflag==1 ? ")" : ""); } } return 0; } ll judge(ll *a,ll *b,ll *flag) { ll minusflag = 0; ll gcd1; if(*a<0)//分子小于0时为负数,标记 { minusflag = 1; *a = fabs(*a);//求最大公约数时需均为正整数 } if((gcd1 = gcd(*a,*b))!=1) { *a = *a / gcd1; *b = *b / gcd1;//消去公约数注意两个不能都用a = a/gcd(a,b)这种形式因为在第一条执行后a的值已经变了,这样得出的b会错误,一开始这么写了。。 } if(*a>*b && *b!=1) { *flag = *a / *b; *a %= *b; //分子大于分母时最简形式 } return minusflag; }