【U218】A-B

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;
}


posted @ 2017-10-06 19:23  AWCXV  阅读(282)  评论(0编辑  收藏  举报