初看这题,觉得并不难。。。。但做了几次都超时。。。。。。。。。。。。。。
a/b + c/d
Time Limit: 2000/1000ms (Java/Others)
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
其实主要是求最大公约数。。。。。。。。。。
先看超时代码:
1 #include<stdio.h> 2 #include<math.h> 3 int main() 4 { 5 int n,m,t,a,b,c,d,e,f,i; 6 scanf("%d",&n); 7 while(n--) 8 { 9 scanf("%d %d %d %d",&a,&b,&c,&d); 10 e=a*d+b*c; 11 f=b*d; 12 if(e>f) 13 t=f; 14 else 15 t=e; 16 for(i=t;i>1;i--) 17 { 18 if(e%i==0&&f%i==0) 19 { 20 e/=i; 21 f/=i; 22 break; 23 } 24 } 25 printf("%d %d\n",e,f); 26 } 27 return 0; 28 }
当数够大时比如1000遍947 971 953 977.
肯定会超时。
然后我去网上查了一下计算最大公约数的方法。(应该算是作弊吧)
求最大公约数算法:
(1)辗转相除法
两整数a和b:
① a%b得余数c
② 若c=0,则b即为两数的最大公约数,结束
③ 若c≠0,则a=b,b=c,再回去执行①
(2)相减法
两整数a和b:
① 若a>b,则a=a-b
② 若a<b,则b=b-a
③ 若a=b,则a(或b)即为两数的最大公约数,结束
④ 若a≠b,则再回去执行①
(3)穷举法:
① i= a b中的小数
② 若a,b能同时被i整除,则i即为最大公约数,结束
③ i--,再回去执行②
相关代码:
1 #include <stdio.h> 2 int xc_gcd(int a,int b) 3 { 4 int c; 5 c=a%b; 6 while( c!=0 ) 7 { 8 a=b; 9 b=c; 10 c=a%b; 11 } 12 return b; 13 } 14 int xj_gcd(int a,int b) 15 { 16 while( a!=b ) 17 { 18 if ( a>b ) 19 a-=b; 20 else 21 b-=a; 22 } 23 return b; 24 } 25 int qj_gcd(int a,int b) 26 { 27 int i; 28 i=(a>b)?a:b; 29 while( a%i!=0 && b%i!=0 ) 30 i--; 31 return i; 32 }
所以用这个方法就很快可以A了
A的代码:
1 #include <stdio.h> 2 int main() 3 { 4 int n,a,b,c,d,e,f,g; 5 int gcd(int,int); 6 scanf("%d",&n); 7 while(n--) 8 { 9 scanf("%d %d %d %d",&a,&b,&c,&d); 10 e=a*d+b*c; 11 f=b*d; 12 g=gcd(e,f); 13 printf("%d %d\n",e/g,f/g); 14 } 15 return 0; 16 } 17 int gcd(int a,int b) 18 { 19 int c; 20 c=a%b; 21 while( c!=0 ) 22 { 23 a=b; 24 b=c; 25 c=a%b; 26 } 27 return b; 28 }