【PTA 7-3】N个数求和 负数GCD

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Xylon_/article/details/87690499

                                7-3 N个数求和 (20 分)

本题的要求很简单,就是求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++库函数里的__gcd( )函数是不能求负数的,我也自然而然地认为负数没有gcd,第一次被库函数坑到,还是手写好  _(:з」∠)_ 

了解这一点后整个过程就是分数通分过程,处理好输出格式就好

代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cstdio>
#include<cmath>
#include<set>
#include<map>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a))
#define closeio std::ios::sync_with_stdio(false)

int gcd(int a,int b)		//最大公约数 
{
    if(a==0&&b==0)
        return -1;
    if(a<0)
        a=-a;
    if(b<0)
        b=-b;
    if(b==0)
        return a;
    return gcd(b,a%b);
}

int gcm(int a,int b)		//最小公倍数 
{
	return a*b/gcd(a,b);
}

int main() 
{
	int n,i,t,a,b,x,y;
	cin>>n;
	scanf("%d/%d",&a,&b);
	t=gcd(a,b);
	a/=t;
	b/=t;
	for(i=1;i<n;i++)
	{
		scanf("%d/%d",&x,&y);
		t=gcm(b,y);
		a=a*t/b+x*t/y;
		b=t;
		t=gcd(a,b);
		a/=t;
		b/=t;
	}
	//cout<<a<<"/"<<b<<endl;
	if(a&&a/b==0)
		cout<<a<<"/"<<b<<endl;
	else if(a%b==0)
		cout<<a/b<<endl;
	else
	{
		cout<<a/b;
		if(a<0)
			a*=-1;
		cout<<" "<<a%b<<"/"<<b<<endl; 
	}
	return 0;
}

顺便附上用了__gcd( )函数的代码(调试了n遍之后神™AC了)

#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cstdio>
#include<cmath>
#include<set>
#include<map>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a))
#define closeio std::ios::sync_with_stdio(false)

struct ac
{
	ll x,y;
	int flag;
}a[105];

ac pri(ac x,ac y)
{
	//cout<<"***"<<x.x<<"/"<<x.y<<" "<<y.x<<"/"<<y.y<<endl;
	int t=__gcd(x.y,y.y);
	if(t==1)
	{
		int ty=x.y;
		x.x*=y.y;
		x.y*=y.y;
		y.x*=ty;
		y.y*=ty;
	}
	else
	{
		int gcm=x.y*y.y/t;
		x.x*=gcm/x.y;
		x.y=gcm;
		y.x*=gcm/y.y;
		y.y=gcm;
	}
	//cout<<"---"<<x.x<<"/"<<x.y<<" "<<y.x<<"/"<<y.y<<endl;
	if(x.flag==1)
	{
		if(y.flag==1)
			x.x+=y.x;
		else
		{
			x.x-=y.x;
			if(x.x<0)
			{
				x.x*=-1;
				x.flag*=-1;
			}
		}
	}
	else
	{
		if(y.flag==1)
		{
			x.x-=y.x;
			if(x.x<0)
			{
				x.x*=-1;
				x.flag*=-1;
			}
		}
		else
			x.x+=y.x;		
	}
	//cout<<"+++"<<x.x<<"/"<<x.y<<endl;
	while(__gcd(x.x,x.y)!=1)
	{
		t=__gcd(x.x,x.y);
		x.x/=t;
		x.y/=t;
	}
	//cout<<"^^^"<<x.x<<"/"<<x.y<<endl;
	return x;
}

int main()
{
	int n,i;
	cin>>n;
	for(i=1;i<=n;i++)
	{
		scanf("%lld/%lld",&a[i].x,&a[i].y);
		if(a[i].x<0)
		{
			a[i].flag=-1;
			a[i].x*=-1;
		}
		else
			a[i].flag=1;
		int tt=__gcd(a[i].x,a[i].y);
		if(tt!=1)
		{
			a[i].x/=tt;
			a[i].y/=tt;
		}
	}
	a[0]=a[1];
	for(i=2;i<=n;i++)
		a[0]=pri(a[0],a[i]);
	//cout<<a[0].x<<"/"<<a[0].y<<endl;
	int tx=a[0].x/a[0].y,ty=a[0].x%a[0].y;
	if(tx)
	{
		if(a[0].flag==-1)
			cout<<"-"; 
		cout<<tx;
		if(ty)
			cout<<" "<<ty<<"/"<<a[0].y<<endl;
	}
	else
	{
		if(ty)
		{
			if(a[0].flag==-1)
				cout<<"-"; 
			cout<<ty<<"/"<<a[0].y<<endl;
		}	
		else
			cout<<"0"<<endl;
	} 
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Xylon_/article/details/87690499