PAT 甲级 1081 Rational Sum 分数处理问题

分数问题,一些小细节的处理特别麻烦,我这里采用的是别人整理好的系统化的方法来进行处理,下面讲解一下思路:

  1. 这里的分数同一采用假分数的形式来处理,并且规定分母都为正,即如果分母为负数,上下同时取反,数0的写法为分子为0,分母为1
  2. 化简时,求出分子分母的最大公约数(PS:这里规定求解时都转化成正数,有兴趣的可以百度一下负数的gcd就明白了),然后同时除以最大公约数即可
  3. 关于输出最后的结果,有下列三种情况:
  • 分母为1,表示结果为整数,输出分子即可
  • 分子大于分母,转为带分数的形式,注意这里符号和整数部分在一起,然后输出分子取模分母的结果(关于负数的取模运算,有兴趣的百度一下,蛮有意思的,计算机会自动转成绝对值运算,然后符号跟左边的数一致)
  • 最后一种情况就是正常的分数,直接输出即可
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
struct frac{
	int up,down;
};
int gcd(int a,int b)//最大公约数不考虑负数
{
	if(b==0)return a;
	else return gcd(b,a%b);
}
frac simplify(frac a)//保证分母大于0,符号看分子 
{
	//分母为负数
	if(a.down<0){
		a.up*=-1;
		a.down*=-1;
	} 
	//分子为0
	if(a.up==0)a.down=1;
	else 
	{
		int t=gcd(abs(a.up),abs(a.down));
		a.up/=t;
		a.down/=t;
	}
	return a;
}
frac add(frac a,frac b)
{
	frac result;
	result.down=a.down*b.down;
	result.up=a.up*b.down+a.down*b.up;
	return simplify(result);
}
int main()
{
	int n;
	cin>>n;
	frac sum,temp;
	sum.up=0;sum.down=1;
	for(int i=0;i<n;i++)
	{
		scanf("%d/%d",&temp.up,&temp.down);
		sum=add(sum,temp);
	}
	if(sum.down==1)cout<<sum.up/sum.down;
	else if(abs(sum.up)<sum.down)
	printf("%d/%d",sum.up,sum.down);
	else 
	{
		printf("%d %d/%d",sum.up/sum.down,abs(sum.up)%sum.down,sum.down); 
	} 
}

猜你喜欢

转载自blog.csdn.net/weixin_42240667/article/details/108189111