UESTCOJ506 分数的运算

题目重述
读入4个整数a、b、c、d和一个运算符(‘+’、‘-’、‘*’、‘/’中的一个),进行分数a/b和c/d的对应运算,输出最简结果。
Standard Input
有多组测试数据。输入的第一行是整数T(1<=T<=200),表示随后测试数据的组数。每组测试数据占一行,由四个正整数a,b,c,d和一个运算符组成,相邻数据间有一个空格。
Standard Output
对应每组测试数据,输出分数运算的最简结果,占一行。具体可参照样例。
在这里插入图片描述
这道题的代码量比较大,但是只要想清楚了思路,那么四种不同运算问题就迎刃而解了,用结构体存储一个分数的分子和分母,最重要的算法是在deal函数中!对计算结果进行一个处理,如果分母是负数,那么把负数扔到分子上去(独立判断),如果分子为零了,则让分母为1(在main函数中有对分子的判断,如果是1则输出分母,这样的话分子是否为0都没有矛盾),其次才是调用gcd()求最大公约数来约分哦。在四则运算函数中,注意一点就是返回的值是deal(res)而不是res,或者处理了仍然返回res(×)。最后一点也是最重要的,高考前老生常谈的事情,一定要先认认真真读题!题目要求的输出运算式,不是最终计算结果!

#include<bits/stdc++.h>
using namespace std;
//定义分数的结构
struct Frac{
	int up;
	int down;
};
//gcd
int gcd(int a,int b)
{
	int t,k;
	if(a<b){
		t=a;
		a=b;
		b=t;
	}
	do{
		k=a%b;
		a=b;
		b=k;
	}while(k!=0);
	return a;
}
//对分数进行化简处理
Frac deal(Frac res)
{
	if(res.down<0){
		res.down=-res.down;
		res.up=-res.up;
	}
	if(res.up==0){
		res.down=1;//这步归一尤其重要!
	}else{
		int t=gcd(abs(res.up),abs(res.down));
		res.up=res.up/t;
		res.down=res.down/t;
	}
	return res;
}
//+
Frac add(Frac f1,Frac f2)
{
	Frac res;
	res.up=f1.up*f2.down+f1.down*f2.up;
	res.down=f1.down*f2.down;
	return deal(res);	
}
//-
Frac min(Frac f1,Frac f2)
{
	Frac res;
	res.up=f1.up*f2.down-f1.down*f2.up;
	res.down=f1.down*f2.down;
	return deal(res);
}
//*
Frac mul(Frac f1,Frac f2)
{
	Frac res;	
	res.up=f1.up*f2.up;
	res.down=f1.down*f2.down;
	return deal(res);	
}
///
Frac div(Frac f1,Frac f2)
{
	Frac res;
	res.up=f1.up*f2.down;
	res.down=f1.down*f2.up;
	return deal(res);
}

main()
{	
	int T;
	Frac f1,f2;
	char x;
	cin>>T;
	while(T--){
		cin>>f1.up>>f1.down>>f2.up>>f2.down>>x;
		if(x=='+'){
			Frac res=add(f1,f2);
			//cout<<gcd(abs(res.up),abs(res.down))<<endl;//如果处理好了就应该是1哦
			if(res.down==1) printf("%d/%d+%d/%d=%d\n",f1.up,f1.down,f2.up,f2.down,res.up);//题目要求输出计算式
			else printf("%d/%d+%d/%d=%d/%d\n",f1.up,f1.down,f2.up,f2.down,res.up,res.down);
		} 
		if(x=='-'){
			Frac res=min(f1,f2);
			if(res.down==1) printf("%d/%d-%d/%d=%d\n",f1.up,f1.down,f2.up,f2.down,res.up);
			else printf("%d/%d-%d/%d=%d/%d\n",f1.up,f1.down,f2.up,f2.down,res.up,res.down);
		} 
		if(x=='*'){
			Frac res=mul(f1,f2);
			if(res.down==1) printf("%d/%d*%d/%d=%d\n",f1.up,f1.down,f2.up,f2.down,res.up);
			else printf("%d/%d*%d/%d=%d/%d\n",f1.up,f1.down,f2.up,f2.down,res.up,res.down);
		} 
		if(x=='/'){
			Frac res=div(f1,f2);
			if(res.down==1) printf("%d/%d/%d/%d=%d\n",f1.up,f1.down,f2.up,f2.down,res.up);
			else printf("%d/%d/%d/%d=%d/%d\n",f1.up,f1.down,f2.up,f2.down,res.up,res.down);
		} 
	}
	return 0;
}

示例输出:

4
1 2 3 4 -
1/2-3/4=-1/4
35 24 24 5 *
35/24*24/5=7
25 72 9 5 /
25/72/9/5=125/648
7 5 1 5 -
7/5-1/5=6/5
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr.zwX

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值