关于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语言代码(无数组):
建议用devc++编译
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 #include<stdio.h>
2 #include<math.h>
3 long int mygcd(long int a,long int b);
4 void simplify(long int *up,long int *down,long int gcd);
5 int main()
6 {
7 int N;
8 scanf("%d",&N);
9 long int up[N],down[N];
10 for(int i=0;i<N;i++) //输入分子、分母
11 {
12 scanf("%ld/%ld",&up[i],&down[i]);
13 }
14 long int gcd;
15 long int up1 = up[0];
16 long int down1 = down[0];
17 simplify(&up1, &down1, mygcd(up1,down1));
18 for(int i=1; i<N;i++)
19 {
20 if(up1!=0) //前i-1项和不为0时
21 {
22 long int temp;
23 simplify(&up1, &down1, mygcd(up1,down1)); //对前i-1项和进行化简
24 gcd = mygcd(down1,down[i]); //求前i-1项和的分母与第i项分母的最大公约数
25 temp = down1;
26 down1 = down1*down[i]/gcd; //求前i-1项和的分母与第i项分母的最小公倍数
27 up1 *= down1/temp; //分子分母同时放大
28 up[i] *= down1/down[i];
29 up1 += up[i];
30 }
31 else //前i-1项和为0
32 {
33 down1 = down[i];
34 up1 = up[i];
35 }
36 }
37 simplify(&up1, &down1, mygcd(up1,down1)); //对最后一次计算结果进行化简
38 if(up1==0) //打印结果
39 {
40 printf("0");
41 }
42 else if(up1/down1==0)
43 {
44 printf("%ld/%ld",up1,down1);
45 }
46 else if(up1%down1==0)
47 {
48 printf("%ld",up1/down1);
49 }
50 else
51 {
52 printf("%ld %ld/%ld",up1/down1,up1%down1,down1);
53 }
54 return 0;
55 }
56
57 long int mygcd(long int a,long int b) //计算最大公约数
58 {
59 a = fabs(a); //考虑a为负数
60 long int r;
61 do
62 {
63 r = a%b;
64 a = b;
65 b = r;
66 }while(r!=0);
67 return a;
68 }
69
70 void simplify(long int *up,long int *down,long int gcd) //分数化简
71 {
72 *up /= gcd;
73 *down /= gcd;
74 }
文末
感谢大家观看本文,也希望大佬们多多指点。 2021-05-1701:05:28

浙公网安备 33010602011771号