Time Limit: 1 second
Memory Limit: 128 MB
【问题描述】
给出一个A/B-C/D表示的分数减法算式,A,B,C,D均为不超过32767的正整数,求A/B-C/D的差,若差为整数,则输出这个整数;若差为分数,则按A/B格式输出;要求为最简分数,若差为负数,则在上述要求下最前面添加负号。 输入中A/B或C/D有可能不是最简分数,但是你的输出必须是最简分数。【输入格式】
输入文件aminusb.in的第1行为一个正整数T,表示数据组数, 接下来T行,每行为按A/B-C/D格式给出的算式。
【输出格式】
输出文件aminusb.out包括T行,分别对于每个算式给出答案。
【数据规模】
对于30%的数据,有T≤10; 对于100%的数据,有T≤10000。
Sample Input1
3 1/3-1/2 10/4-2/2 3/2-1/2
Sample Output1
-1/6 3/2 1
【题解】
C++可以直接用scnaf过滤掉-和/。所以读入a,b,c,d不是问题。 然后对于输入的a,b获取他们的最大公因数k。然后同时除掉k。 c和d也是一样。同时除k。 然后a/b-c/d用通分的方法 = (a*d-b*c)/(b*d) 然后一开始符号为正(1),若是分子为负数,把分子取相反数,然后符号为1-flag == 0(负数); 如果分母也是负号,则分母也取反。然后符号为1-flag == 1(正数); 最后如果符号为负,则输出一个“-”,然后输出分子/分母的形式即可。
【代码】
#include <cstdio>
int t,a,b,c,d;
int gcd(int a, int b) //获取a和b的最大公因数。
{
if (b == 0)
return a;
else
return gcd(b, a % b);
}
int main()
{
scanf("%d", &t);
for (int i = 1; i <= t; i++) //输入t组数据
{
scanf("%d/%d-%d/%d", &a, &b, &c, &d); //可以直接过滤出a,b,c,d;
int k = gcd(a, b);//获取a和b的最大公因数。
a /= k;
b /= k;//模拟约分过程
k = gcd(c, d); //获取c和d的最大公因数。
c /= k;//模拟约分
d /= k;
bool flag = 1; //最后答案的符号
int fenzi = a*d - b*c;
if (fenzi < 0) //分子为负数改变答案符号
{
flag = 1 - flag;
fenzi = -fenzi; //同时保证分子和分母都是非负数。
}
int fenmu = b*d;
if (fenmu < 0)//分母为负数改变答案符号。
{
flag = 1 - flag;
fenmu = -fenmu;
}
if (!flag)//如果最后答案是负数则输出一个负号
printf("-");
k = gcd(fenzi, fenmu); //最后的分子和分母也要进行一次约分操作。
fenzi /= k;
fenmu /= k;
if (fenmu == 1 || fenzi == 0) //如果分母是1或者分子是0则输出一个整数。(分子和0)
printf("%d\n", fenzi);
else //否则按照分数的形式正常输出即可。
printf("%d/%d\n", fenzi, fenmu);
}
return 0;
}