5kyu Some Egyptian fractions

5kyu Some Egyptian fractions

题目背景:

Given a rational number n

as a string (example: “2/3” in Ruby, Python, Clojure, JS, CS, Go) or as two strings (example: “2” “3” in Haskell, Java, CSharp, C++, Swift) decompose this number as a sum of rationals with numerators equal to one and without repetitions (2/3 = 1/2 + 1/6 is correct but not 2/3 = 1/3 + 1/3, 1/3 is repeated).

The algorithm must be “greedy”, so at each stage the new rational obtained in the decomposition must have a denominator as small as possible. In this manner the sum of a few fractions in the decomposition gives a rather good approximation of the rational to decompose.

2/3 = 1/3 + 1/3 doesn’t fit because of the repetition but also because the first 1/3 has a denominator bigger than the one in 1/2 in the decomposition 2/3 = 1/2 + 1/6.

题目分析:

埃及分数是很有趣的一个数字的性质,本道题本质上是数学上的问题分析,对于大于1的部分,直接分子除以分母获取大于1的那部分整数即可;对于拆解出的小于1的部分,如果分母可以整除了分子,那么说明埃及分数的迭代结束,而倘若不能够整除,需要用到贪心思想,去找到最小的分母,譬如 6 / 14, 那么它可以生成的数里面,最小的分母是 14 / 6 (c++中int 除以 int会下取整得到int型结果 ) + 1 = 3 ,于是6 / 14 = 1 / 3 + ((3 * 6) - 14) / (3 * 14) = 1 / 3 + 4 / 42 ,按照这个思路就可以写出整个程序。

AC代码:

using namespace std;

class Decomp{
public:
  static string decompose(const string &nrStr, const string &drStr);
};

string Decomp::decompose(const string &nrStr, const string &drStr){
    long nr = std::stol(nrStr);
    long dr = std::stol(drStr);
    if ( nr == 0 || dr == 0 ) return "[]";
    string res = "[";
    while ( nr != 0 && dr != 0 ) {
        if ( nr >= dr ) {
            res += std::to_string(nr / dr);
            nr -= (nr / dr) * dr;
        }
        else {
            res += "1/";
            long tmp;
            if ( dr % nr == 0 ) tmp = dr / nr;
            else tmp = dr / nr + 1;
            res += std::to_string(tmp);
            nr = nr * tmp - dr;
            dr = dr * tmp;
        }
        res += ", ";
    }
    res = res.substr(0, res.size() - 2) + "]";
    return res;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值