4

关于N个有理分数求和的分析(c语言)

题目要求

本题的要求很简单,就是求N个数字的和。麻烦的是,这些数字是以有理数分子/分母的形式给出的,你输出的和也必须是有理数的形式。

输入格式:

输入第一行给出一个正整数N≤100)。随后一行按格式a1/b1 a2/b2 ...给出N个有理数。题目保证所有分子和分母都在长整型范围内。另外,负数的符号一定出现在分子前面。

输出格式:

输出上述数字和的最简形式 —— 即将结果写成整数部分 分数部分,其中分数部分写成分子/分母,要求分子小于分母,且它们没有公因子。如果结果的整数部分为0,则只输出分数部分。

输入样例1:

5 2/5 4/15 1/30 -2/60 8/3

输出样例1:

3 1/3
 

输入样例2:

2 4/3 2/3
 

输出样例2:

2
 

输入样例3:

3 1/3 -1/6 1/8
 

输出样例3:

7/24

编写示例


下面让我们看一段c语言代码(无数组):
1 #include<stdio.h> 2 int GCD(int x,int y); 3 int LCM(int x,int y); 4 int main() 5 { 6 int n,x,y,i,a=0,b=0,m,t,k,f=0; 7 scanf("%d\n",&n); 8 for(i=1;i<=n;i++) 9 { 10 x=a;//储存两个有理分数其中一个分子 11 y=b;//储存x的分母 12 scanf("%d/%d",&a,&b);//输入两个整数,前者是分子,后者是分母 13 if(i==1) 14 { 15 continue;//第一次x,y没有存储到我们输入的值,所以不能执行下面的代码 16 } 17 t=LCM(b,y);//求出两个有理分数中分母的最小公倍数(LCM)来进行分子的求和运算 18 a=(t/b)*a+(t/y)*x;//两个有理分数求和后的一个新的有理分数的分子 19 b=t;//新有理分数中的分母// 20 } 21 if(a>=b)//如果分子不小于分母,则则可以分离出一个整数部分k 22 { 23 k=a/b; 24 printf("%d",k); 25 a=a-k*b;//此时的a为有理化后的分数部分的分子 26 f=1;//作为a经过一次有理化之后的标志 27 } 28 if(a==0&&f==1) 29 { 30 //如果a为0且f为1,则说明该有理分数求和时只得出了整数且该整数不为0 31 } 32 else if(a==0&&f==0) 33 { 34 printf("0");//如果a为0且f为0,则说明有理分数求和时只得出了整数且该整数为0 35 } 36 else /*除了上述两个条件之外,无论是求和结果得出了整数和有理分数还是只得出了有理分数, 37 总之存在一个有理分数a/b(若f为1,则a是求和后分离出整数之后的新分子但我们为了简便还用a表示; 38 若f为0,则a就是求和之后的分子)*/ 39 { 40 m=GCD(a,b); 41 a/=m; 42 b/=m; 43 printf("%d/%d\n",a,b); 44 } 45 return 0; 46 } 47 int GCD(int x,int y) 48 { 49 int c; 50 c=x%y; 51 while(c!=0) 52 { 53 x=y; 54 y=c; 55 c=x%y; 56 } 57 return y; 58 } 59 int LCM(int x,int y) 60 { 61 int temp, i; 62 if(x<y) 63 { 64 temp = x; 65 x= y; 66 y = temp; 67 } 68 for(i=x; i>0; i++) 69 if(i%x==0&&i%y==0) 70 { 71 return i; 72 break; 73 } 74 }

 

 

出现的问题

经过运行之后我们发现输出结果与示例的结果均一致,但我们提交到做题系统后,却只得了一半的分。(出现的问题)

解决方案

这是我们才发现系统判错很公道,我们忘记了随时化简可能导致了数据溢出,而且我们忽略了输出负整数和整数的情况。 通过进一步学习与调整,我们得出这套代码:
1 1 #include<stdio.h> 2 2 #include<math.h> 3 3 long int mygcd(long int a,long int b); 4 4 void simplify(long int *up,long int *down,long int gcd); 5 5 int main() 6 6 { 7 7 int N; 8 8 scanf("%d",&N); 9 9 long int up[N],down[N]; 10 10 for(int i=0;i<N;i++) //输入分子、分母 11 11 { 12 12 scanf("%ld/%ld",&up[i],&down[i]); 13 13 } 14 14 long int gcd; 15 15 long int up1 = up[0]; 16 16 long int down1 = down[0]; 17 17 simplify(&up1, &down1, mygcd(up1,down1)); 18 18 for(int i=1; i<N;i++) 19 19 { 20 20 if(up1!=0) //前i-1项和不为0时 21 21 { 22 22 long int temp; 23 23 simplify(&up1, &down1, mygcd(up1,down1)); //对前i-1项和进行化简 24 24 gcd = mygcd(down1,down[i]); //求前i-1项和的分母与第i项分母的最大公约数 25 25 temp = down1; 26 26 down1 = down1*down[i]/gcd; //求前i-1项和的分母与第i项分母的最小公倍数 27 27 up1 *= down1/temp; //分子分母同时放大 28 28 up[i] *= down1/down[i]; 29 29 up1 += up[i]; 30 30 } 31 31 else //前i-1项和为0 32 32 { 33 33 down1 = down[i]; 34 34 up1 = up[i]; 35 35 } 36 36 } 37 37 simplify(&up1, &down1, mygcd(up1,down1)); //对最后一次计算结果进行化简 38 38 if(up1==0) //打印结果 39 39 { 40 40 printf("0"); 41 41 } 42 42 else if(up1/down1==0) 43 43 { 44 44 printf("%ld/%ld",up1,down1); 45 45 } 46 46 else if(up1%down1==0) 47 47 { 48 48 printf("%ld",up1/down1); 49 49 } 50 50 else 51 51 { 52 52 printf("%ld %ld/%ld",up1/down1,up1%down1,down1); 53 53 } 54 54 return 0; 55 55 } 56 56 57 57 long int mygcd(long int a,long int b) //计算最大公约数 58 58 { 59 59 a = fabs(a); //考虑a为负数 60 60 long int r; 61 61 do 62 62 { 63 63 r = a%b; 64 64 a = b; 65 65 b = r; 66 66 }while(r!=0); 67 67 return a; 68 68 } 69 69 70 70 void simplify(long int *up,long int *down,long int gcd) //分数化简 71 71 { 72 72 *up /= gcd; 73 73 *down /= gcd; 74 74 } 75

文末

感谢大家观看本文,也希望大佬们多多指点。                                                                 2021-05-1701:05:28

 

__EOF__

本文作者梦泽ovo
本文链接https://www.cnblogs.com/mengze/p/14775532.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   梦泽ovo  阅读(1293)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示