zoukankan      html  css  js  c++  java
  • 5-35 有理数均值

    本题要求编写程序,计算N个有理数的平均值。

    输入格式:

    输入第一行给出正整数 N(≤ 100);第二行中按照a1/b1 a2/b2 …的格式给出 N 个分数形式的有理数,其中分子和分母全是整形范围内的整数;如果是负数,则负号一定出现在最前面。

    输出格式:

    在一行中按照a/b的格式输出N个有理数的平均值。注意必须是该有理数的最简分数形式,若分母为1,则只输出分子。

    输入样例1:

    4
    1/2 1/6 3/6 -5/10
    

    输出样例1:

    1/6
    

    输入样例2:

    2
    4/3 2/3
    

    输出样例2:

    1
    

    解题思路:

    先将各个分数通分。然后相加,乘以 1/N 之后再利用辗转相除法化简分数,得到最终值。

    其中遇到的问题及思路整理:

    之前的想法是将所有的分母累乘起来,然后再求公约数。结果后两例出现错误。思考原因应该是分母的累乘有可能会超过 int 型的表示范围。于是改成每两个分数就进行一次化简操作。这样两个分母的相乘的最大值应该是 int 型范围值最大值的平方。还是有可能超过 int 的表示范围。先提交测试测试,发现第 3 个用例依然错误。

    有符号的 int 型表示范围上限为 2^31-1(这是 int 型占用 4 个字节时的情况,不同编译器可能有所差别),那么最大的那个值可能是 (2^31-1)^2,难道要换成 double 型?double 型占用 8 个字节,正好满足它的范围。可是 double 型不能进行求余,也就意味着不能利用辗转相除法化简分母。其实 C99 还定义了一种长长整型,即 long long int 型,占用 8 个字节。也是刚好满足这个范围的。

    解题代码:

    #include<stdio.h>
    
    struct fraction {
    	long long int numerator;
    	long long int denominator;
    }; 
    
    void add (struct fraction f[], int i, int j);
    void reduction (struct fraction f[], int i);
    
    int main ()
    {
    	int N;
    	scanf ("%d", &N);
    	 
    	struct fraction f[N]; 
        
    	for (int i=0; i<N; i++) {
    		scanf ("%lld/%lld", &f[i].numerator, &f[i].denominator);
    		if (i >= 1) {
    			reduction (f, i); // 这里是通分之前的化简,可有可无的。
     			add (f, i-1, i);
     			reduction (f, i);
    		}
    	}
    	
    	f[N-1].denominator *= N; //分母乘以 N 求平均数 
    	reduction (f, N-1); 
    
    	if (f[N-1].denominator == 1) {
    		printf ("%lld
    ", f[N-1].numerator);
    	} else {
    		printf ("%lld/%lld
    ", f[N-1].numerator, f[N-1].denominator);
    	}
    	return 0; 
    }
    
    void reduction (struct fraction f[], int i) {
    	long long int a = f[i].numerator;
    	long long int b = f[i].denominator;
    	if (a < 0) a = -a;  //最大公约数算法不能求负数 
    	long long int temp;
    	while (b > 0) {
    		temp = a % b;
    		a = b;
    		b = temp; 
    	}
    	f[i].numerator /= a;
    	f[i].denominator /= a;
    } // 化简分数 
    
    void add (struct fraction f[], int i, int j) {
    	f[i].numerator *= f[j].denominator;
    	f[j].numerator *= f[i].denominator;
    	f[i].denominator *= f[j].denominator;
    	f[j].denominator = f[i].denominator;
    	f[j].numerator += f[i].numerator;
    } // 通分并相加
  • 相关阅读:
    HDOJ 4747 Mex
    HDU 1203 I NEED A OFFER!
    HDU 2616 Kill the monster
    HDU 3496 Watch The Movie
    Codeforces 347A A. Difference Row
    Codeforces 347B B. Fixed Points
    Codeforces 372B B. Hungry Sequence
    HDU 1476 Sudoku Killer
    HDU 1987 How many ways
    HDU 2564 词组缩写
  • 原文地址:https://www.cnblogs.com/andywenzhi/p/5738644.html
Copyright © 2011-2022 走看看