B1034 有理数四则运算

该程序设计任务是计算两个有理数的加减乘除,并确保结果是最简形式。输入包括两个分数,输出是它们的运算结果,需要注意负数、分母为0的情况及整型溢出问题。代码实现时需使用`long long`类型以防止运算过程中的溢出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

注:此题陷阱很多

  1. 输入时分母虽然不会是负数,但是除法后的分母有可能是负数,所以必须注意
  2. 最大的陷阱是题目的最后一句话:“题目保证正确的输出中没有超过整型范围的整数 ”,这很容易让人断定只需要用int型就可以了,这就是陷阱的厉害之处!!!因为输出的都是化简后的答案,而在运算过程中两个int型相乘会产生溢出!!!所以要用long long型。

注:很多题目的陷阱都是利用数据范围这个点出的,这值得去注意,考虑必须要全面

参考代码

#include <cstdio>
#include <algorithm>
using namespace std;
struct fraction{
  long long up, down;   //这里必须使用long long型,两个int型相乘可能会溢出!!!
}f1, f2;
int gcd(long long a, long long b){    //这里的a,b也是同理,需要long long型否则会溢出!!!
  return b==0 ? a : gcd(b, a%b);
}
fraction reduction(fraction r){
  if(r.down<0){
    r.up=-r.up;
    r.down=-r.down;
  }
  if(r.up==0) r.down=1;
  else{
    int d=gcd(abs(r.up), abs(r.down));
    r.up/=d;
    r.down/=d;
  }
  return r;
}
fraction add(fraction f1, fraction f2){
  fraction r;
  r.up=f1.up*f2.down+f2.up*f1.down;
  r.down=f1.down*f2.down;
  return reduction(r);
}
fraction sub(fraction f1, fraction f2){
  fraction r;
  r.up=f1.up*f2.down-f2.up*f1.down;
  r.down=f1.down*f2.down;
  return reduction(r);
}
fraction mult(fraction f1, fraction f2){
  fraction r;
  r.up=f1.up*f2.up;
  r.down=f1.down*f2.down;
  return reduction(r);
}
fraction divide(fraction f1, fraction f2){
  fraction r;
  r.up=f1.up*f2.down;
  r.down=f1.down*f2.up;
  reduction(r);
  return reduction(r);
}
void print(fraction res){   
  fraction r=reduction(res);
  if(r.up<0) printf("(");
  if(r.down==1) printf("%lld", r.up);
  else if(abs(r.up)>r.down){
    printf("%lld %lld/%lld", r.up/r.down, abs(r.up)%r.down, r.down);
  }
  else printf("%lld/%lld", r.up, r.down);
  if(r.up<0) printf(")");
}
int main(){
  scanf("%lld/%lld %lld/%lld", &f1.up, &f1.down, &f2.up, &f2.down);
  print(f1);
  printf(" + ");
  print(f2);
  printf(" = ");
  print(add(f1, f2));
  printf("\n");
  
  print(f1);
  printf(" - ");
  print(f2);
  printf(" = ");
  print(sub(f1, f2));
  printf("\n");
  
  print(f1);
  printf(" * ");
  print(f2);
  printf(" = ");
  print(mult(f1, f2));
  printf("\n");
  
  print(f1);
  printf(" / ");
  print(f2);
  printf(" = ");
  fraction r=divide(f1, f2);
  if(r.down==0) printf("Inf");
  else print(r);
  printf("\n");
  return 0;
}

如对你有用就在右上角处点个赞呗!!! biubiu

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值