前言:本期是关于pta题目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
代码实现:
#include<stdio.h>
int com_div(long long x,long long y)
{
int tmp = 0;
while(tmp=x%y)
{
x=y;
y=tmp;
}
return y;
}
int main()
{
int n = 0;
scanf("%d",&n);
int i = 0;
long long a = 0;
long long b = 0;
long long suma = 0;
long long sumb = 0;
for(i=0;i<n;i++)
{
scanf("%lld/%lld",&a,&b);
if(suma==0)
{
suma=a;
sumb=b;
}
else
{
suma=suma*b+a*sumb;
sumb=sumb*b;
}
int max=com_div(suma,sumb);
suma/=max;
sumb/=max;
}
if(suma && (suma/sumb==0))
{
printf("%lld/%lld",suma,sumb);
}
else if(suma%sumb==0)
{
printf("%lld",suma/sumb);
}
else
{
printf("%lld %lld/%lld",suma/sumb,suma%sumb,sumb);
}
return 0;
}
大致思路:
预备了解:
suma:分数的分子和 sumb:分数的分母和
a:分数的分子 b:分数的分母
com_div函数:求出两数的最大公约数 max:存储最大公约数
1. 每输入一次分数,就与之相加,相加通分后的分子,分母化至最简
2. 若输入的是第一个分数:特殊处理
此时代表分子和的suma==0,suma赋值成第一个分数的分子,sumb赋值成第一个分数的分母
若输入的不是第一个分数:
suma存储两个分数通分后的分子和
sumb存储两个分数通分后的分母和
3. 打印:三种形式:只有整数部分 只有分数部分 整数部分+分数部分
只有整数部分: 所有分数相加通分化简后的分子和suma 是分母和sumb的整数倍(即整除)
只有分数部分: 所有分数相加通分化简后的分子和suma比分母和sumb小,且不能为0
0/任意数=0
suma有可能在通分相加过程中变成0,因为存在负数
整数部分+分数部分: 所有分数相加通分化简后的分子和suma比分母和sumb大
(不是sumb的倍数)
整数部分:suma/sumb
分数部分:分子:suma%sumb 分母:sumb
eg. 10/3 对应:整数部分:3 分数部分:1/3
整数部分求法:10/3=3
分数部分求法:分子:10%3=1
分母:3
代码解读:
part 1 求出所有分数相加通分后的分子和,分母和
scanf("%lld/%lld",&a,&b);
if(suma==0)
{
suma=a;
sumb=b;
}
else
{
suma=suma*b+a*sumb;
sumb=sumb*b;
}
for循环内部读取每一个分数的分子a,分母b
若是读取的是第一个分数,需要特殊处理(因为第一个分数无需与其他分数相加通分)
suma赋值成第一个分数的分子a
sumb赋值成仪狄格分数的分母b
若读取的不是第一个分数:(此分数需要与别的分数进行相加通分)
下面是简单的通分代码:
suma=suma*b+a*sumb;
sumb=sumb*b;
part 2 求出最大公约数,每两个分数相加通分后需化简
int max=com_div(suma,sumb);
suma/=max;
sumb/=max;
com_div是求最大公约数的函数
每次两个分数相加通分后所得的新分子(即两个分数的分子和)suma,新分母(即两个分数的分母和)sumb,需要进行化简,除以最大公约数即可化至最简
以下是求最大公约数的函数:使用的是辗转相除法
int com_div(long long x,long long y)
{
int tmp = 0;
while(tmp=x%y)
{
x=y;
y=tmp;
}
return y;
}
part 3 打印
if(suma && (suma/sumb==0))
{
printf("%lld/%lld",suma,sumb);
}
else if(suma%sumb==0)
{
printf("%lld",suma/sumb);
}
else
{
printf("%lld %lld/%lld",suma/sumb,suma%sumb,sumb);
}
输出分三种形式:
1. 只有整数部分
else if(suma%sumb==0)
{
printf("%lld",suma/sumb);
}
2.只有分数部分
if(suma && (suma/sumb==0))
{
printf("%lld/%lld",suma,sumb);
}
3 整数部分+分数部分
else
{
printf("%lld %lld/%lld",suma/sumb,suma%sumb,sumb);
}