法一
题目
本题的要求很简单,就是求
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
问题
输入问题
1,输入样例有两行代码怎么写才能按要求输入
2,分数是如何输入的
3,分子分母都在长整型范围之内,那么什么是长整型
4,如何保证负数的符号一定在分子面前
输出问题
1,如何保证分子小于分母
2,如何保证分子分母没有公因子
整个解题思路问题
1,分数如何求和
2,如何把假分数写成真分数并且真分数中的整数和分数分开写
解决方法
输入
1,
int n,i,m=0;
scanf("%d",&n);
number x[n];
for(i=0;i<n;i++){
scanf("%d/%d",&x[i].fz,&x[i].fm);
}
2,n个分数如何输出
for(i=1;i<n;i++){
x[0].fz=x[0].fz*x[i].fm+x[0].fm*x[i].fz;;
x[0].fm=x[0].fm*x[i].fm;
}
3,长整型long int
4,如果判断是负的则先打印负号
输出
1,如何保证分子小于分母
void pp(int x,int y,int m){
int t,a=x,b=y;;
while(gcb(a,b)!=1){
t=gcb(a,b);
a=a/t;
b=b/t;
}
if(a!=0){
if(m==1){
printf(" ");
}
printf("%d/%d",a,b);
}
}
2,辗转相除法求最大公因数保证分子分母没有公因子
int gcb(int x,int y){
int c,a=x,b=y;
while(a!=0){
c=b%a;
b=a;
a=c;
}
return b;
}
整个解题思路
1,分数如何求和
for(i=1;i<n;i++){
x[0].fz=x[0].fz*x[i].fm+x[0].fm*x[i].fz;;
x[0].fm=x[0].fm*x[i].fm;
}
2,如何把假分数写成真分数并且真分数中的整数和分数分开写
void pp(int x,int y,int m){
int t,a=x,b=y;;
while(gcb(a,b)!=1){
t=gcb(a,b);
a=a/t;
b=b/t;
}
if(a!=0){
if(m==1){
printf(" ");
}
printf("%d/%d",a,b);
}
}
if(x[0].fz==0){
printf("0");
}else{
if(x[0].fz/x[0].fm!=0){
printf("%d",x[0].fz/x[0].fm);
m=1;
}
pp(x[0].fz-(x[0].fz/x[0].fm)*x[0].fm,x[0].fm,m);
}
题解
#include <stdio.h>
typedef struct{
int fz;
int fm;
}number;
int gcb(int x,int y){
int c,a=x,b=y;
while(a!=0){
c=b%a;
b=a;
a=c;
}
return b;
}
void pp(int x,int y,int m){
int t,a=x,b=y;;
while(gcb(a,b)!=1){
t=gcb(a,b);
a=a/t;
b=b/t;
}
if(a!=0){
if(m==1){
printf(" ");
}
printf("%d/%d",a,b);
}
}
int main(){
int n,i,m=0;
scanf("%d",&n);
number x[n];
for(i=0;i<n;i++){
scanf("%d/%d",&x[i].fz,&x[i].fm);
}
for(i=1;i<n;i++){
x[0].fz=x[0].fz*x[i].fm+x[0].fm*x[i].fz;;
x[0].fm=x[0].fm*x[i].fm;
}
if(x[0].fz==0){
printf("0");
}else{
if(x[0].fz/x[0].fm!=0){
printf("%d",x[0].fz/x[0].fm);
m=1;
}
pp(x[0].fz-(x[0].fz/x[0].fm)*x[0].fm,x[0].fm,m);
}
}
法二
#include<stdio.h>
int fun(int x,int y)//辗转相除法求最大公因数保证分子分母没有公因子
{
int z=y;
while(x%y!=0)
{
z=x%y;
x=y;
y=z;
}
return z;
}
int main()
{
int flag=0;//处理负号问题
int i,sum1=0,sum2=0,n,t;
scanf("%d",&n);
int arr[n][2];//分子分母两类数字用二维数组表示
for(i=0;i<n;i++)//循环输入分数
{
scanf("%d/%d",&arr[i][0],&arr[i][1]);
}
sum1=arr[0][0];//分子初始值
sum2=arr[0][1];//分母初始值
for(i=1;i<n;i++)//求和并且化分数为最简
{
sum1=arr[i][0]*sum2+arr[i][1]*sum1;
sum2=sum2*arr[i][1];
t=fun(sum1,sum2);
sum1/=t;
sum2/=t;
}
if(sum1*sum2<0)//答案有以下三种情况
{
flag=1;
if(sum1<0)
{
sum1=-sum1;
}
if(sum2<0)
{
sum2=-sum2;
}
}
if(flag){
printf("-");
}
if(sum1%sum2==0){
printf("%d",sum1);
}
else {
if(sum1>sum2)
{
printf("%d %d/%d",sum1/sum2,sum1%sum2,sum2);
}
else
{
printf("%d/%d",sum1,sum2);
}
}
return 0;
}
相比法一还是法二更容易理解哎,我现在这种基础不好的也能看懂