Java - PAT - L1-009. N个数求和

本题的要求很简单,就是求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

import java.util.Scanner;
public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		String[] s = new String[n];
		long fm2 = 1;
		long sum = 0;
		s[0] = sc.next();
		for(int i=1 ;i<n ;i++){
			s[i] = sc.next();
			if(fm2%getfm(s[i])!=0){			//	防止直接分母全部相乘超范围
				fm2 *= getfm(s[i]);
			}
		}
		for(int i=0 ;i<n ;i++){
			sum += getfz(s[i])*fm2/getfm(s[i]); 
		}
		
		/*大致分类
		 * ① 分母等于0
		 * ②分子(绝对值)小于分母  包括正数和负数
		 * ③分子等于分母
		 * ④分子(绝对值)大于分母  包括正数和负数
		 * 第④种情况就涉及到带分数
		 */
		if(sum==0){		
			System.out.println(0);	
		}else{
			if(Math.abs(sum)<fm2){
				if(gcd(sum,fm2)==1){
					System.out.printf("%d/%d\n",sum,fm2);
				}else{
					System.out.printf("%d/%d\n",sum/gcd(sum,fm2),fm2/gcd(sum,fm2));
				}
			}
			else if(Math.abs(sum)==fm2){
				if(sum<0){
					System.out.println(-1);
				}else{
					System.out.println(1);
				}
			}
			else{
				if(sum<0){
					sum =-sum;
					long x = sum/fm2;
					if(sum%fm2!=0){
						System.out.printf("-%d -%d/%d\n", x,(sum-fm2*x)/gcd((sum-fm2*x),fm2),fm2/gcd((sum-fm2*x),fm2));
					}else{
						System.out.println(-x);
					}
				}else{
					long x = sum/fm2;
					if(sum%fm2!=0){
						System.out.printf("%d %d/%d\n", x,(sum-fm2*x)/gcd((sum-fm2*x),fm2),fm2/gcd((sum-fm2*x),fm2));
					}else{
						System.out.println(x);
					}
				}
			}
		}
    }
	public static long getfz(String s){
		String[]s1 = s.split("/");
		return Long.parseLong(s1[0]);
	}
	public static long getfm(String s){
		String[]s1 = s.split("/");
		return Long.parseLong(s1[1]);
	}
	public static long gcd(long a ,long b){
		if(a<0){
			a=-a;
		}
		if(b<0){
			b= -b;
		}
		if(a<b){
			long temp = a;
			a=b;
			b=temp;
		}
		if(a%b==0){
			return b;
		}else{
			return gcd(b,a%b);
		}
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值