Problem Description
给你2个分数,求他们的和,并要求和为最简形式。
Input
输入首先包含一个正整数T(T<=1000),表示有T组测试数据,然后是T行数据,每行包含四个正整数a,b,c,d(0<a,b,c,d<1000),表示两个分数a/b 和 c/d。
Output
对于每组测试数据,输出两个整数e和f,表示a/b + c/d的最简化结果是e/f,每组输出占一行。
Sample Input
2
1 2 1 3
4 3 2 3
Sample Output
5 6
2 1
我的代码:(辗转相除法求公约数)
#include<stdio.h>
int gy2(int e,int f)
{
int temp;
if(e>f)
{
temp=e;
e=f;
f=temp;
}
int i=f%e;
while(i!=0)
{
f=e;e=i;i=f%e;
}
return e;
}
int main()
{
int t,a,b,c,d,e,f;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d%d",&a,&b,&c,&d);
e=a*d+b*c;
f=b*d;
printf("%d %d\n",e/gy2(e,f),f/gy2(e,f));
}
return 0;
}
当时有考虑从分子分母(e,f)小的为基数,然后i–,求出公约数,但是超时了。所以错误了。
int gy(int e,int f)
{
int i,temp;
if(e>f)
{
temp=e;
e=f;
f=temp;
}
for( i=e; i>0; i--)
{
if(e%i==0&&f%i==0)
break;
}
return i;
补充:关于辗转相除法:
两个整数的最大公约数等于其中较小的数和两数zd的差的最大公约数。例如,252和105的最大公约数是21(252 = 21 × 12;105 = 21 × 5);因为252 − 105 = 147,所以147和105的最大公约数也是21。在这个过程中,较大的数缩小了,所以继续进行同样的计算可以不断缩小这两个数直至其中一个内变成零。这时,所剩下的还没有变成零的数就是两数的最大公约数。由容辗转相除法也可以推出,两数的最大公约数可以用两数的整数倍相加来表示,如21 = 5 × 105 + (−2) × 252
即用大的除小的,写余数,再用大的除小的,除尽了,就是那个数