Java机试题*:将真分数分解为埃及分数(斐波那契求真分数的埃及分数)

描述

分子为1的分数称为埃及分数。现输入一个真分数(分子比分母小的分数,叫做真分数),请将该分数分解为埃及分数。如:8/11 = 1/2+1/5+1/55+1/110。
注:真分数指分子小于分母的分数,分子和分母有可能gcd不为1!
如有多个解,请输出任意一个。
请注意本题含有多组样例输入!

输入描述:

输入一个真分数,String型

输出描述:

输出分解后的string

/**
数学家斐波那契提出的一种求解埃及分数的贪心算法,准确的算法表述应该是这样的:
设某个真分数的分子为a,分母为b;
把c=(b/a+1)作为分解式中第一个埃及分数的分母;
将a-b%a作为新的a;
将b*c作为新的b;
如果a等于1,则最后一个埃及分数为1/b,算法结束;
如果a大于1但是a能整除b,则最后一个埃及分数为1/(b/a),算法结束;
否则重复上面的步骤。
**/
/**
思路1:斐波那契求埃及分数贪心算法:
**/
import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        while(in.hasNext()){
            String res = "";
            String[] arr = in.nextLine().split("/");
            String pre = "";
            int a = Integer.valueOf(arr[0]);
            int b = Integer.valueOf(arr[1]);
            while (true){
                int c = b/a+1;
                res += "1/";
                res += c;
                a = a - b % a;
                b = b * c;
                res += "+";
                if (a == 1){
                    res += "1/";
                    res += b;
                    break;
                }else if (a > 1 && b % a == 0){
                    res += "1/";
                    res += b/a;
                    break;
                }
            }
            System.out.println(res);
        }
    }
}
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
 * 
   * 思路2:通分比较从1/2开始依次比较分子大小,若大于埃及分数,则减去,直到真分数分子为0,这种思路10个用例有一个超时无法通过。
 *
 */
public class Main {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextLine()) {
            String[] num = in.nextLine().split("/");
            long member = Long.valueOf(num[0]);
            long denominator = Long.valueOf(num[1]);
            long tempMember = member;
            long tempDenominator = denominator;
            // 存储拆分的埃及分数分母
            List<Long> ret = new ArrayList<Long>();
            // 从1/2 开始
            long initDenominator = 2;
            while(tempMember > 0) {
                // 求分母的最小公倍数,通分比较大小
                long minMultiple = getMinMultiple(tempDenominator, initDenominator);
                // 通分后分子
                long a = tempMember * (minMultiple / tempDenominator);
                long b = 1 * (minMultiple / initDenominator);
                if(a >= b) {
                    tempMember = a - b;
                    tempDenominator = minMultiple;
                    // 将满足的放入埃及分数分母结果集合
                    ret.add(initDenominator);
                }
                initDenominator++;
            }
            StringBuffer retStr = new StringBuffer();
            for (int i = 0; i < ret.size(); i++) {
                retStr.append("1/" + ret.get(i) + "+");
            }
            System.out.println(retStr.substring(0,retStr.length() - 1));
        }
    }
    
    // 求最大公约数
    public static long gcd(long a,long b) {
        return  b == 0 ? a : gcd(b, a % b);
    }
    
    // 最小公倍数
    public static long getMinMultiple(long m , long n) {
         // 最小公倍数 = 这两个数的乘积 / 最大公约数
         long minMultiple = n * m / gcd(m,n);
         return minMultiple;
    }
}

题目来源:牛客网

参考链接:https://www.nowcoder.com/practice/e0480b2c6aa24bfba0935ffcca3ccb7b?tpId=37&&tqId=21305&rp=1&ru=/ta/huawei&qru=/ta/huawei/question-ranking

 
posted @ 2022-01-24 16:52  对月当歌  阅读(391)  评论(0)    收藏  举报