题意
给定一个真分数 其中 a < b ,求该真分数的最短埃及数分解。
解法
考虑贪心做法 ,试着找一个距离最近的埃及数,即不大于的最大埃及数k,减去 k , 对剩下的 进行同理的分解,即可得到最短的埃及数分解。
如何求出满足限制的最大埃及数 ?
-
给出结论:
-
证明:
考虑:将 b 表示成 , 其中
对两边都除以 a
则有 , 其中
若上式的 , 那么考虑将上式取倒数
因为 , 那么可得
一定是该数的最大埃及数!
由原式 可得 k =
为了将过程表述完整下面给出完整步骤:
- 求出根据公式求出k + 1
- 将 , 求出新的分子分母通分,重复1、2步。
- 当 a = 1 时 即可不再重复以上操作,输出最后的结果即可
参考代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
void solved(){
std::string num;
std::cin >> num;
int a = 0 , i , b = 0;
for (i = 0; num[i] != '/'; i ++ )
a = a * 10 + (num[i] - '0');
i ++; // 移到数字位
for (;i < int(num.size()); i ++ )
b = b * 10 + (num[i] - '0');
std::cout << a << '/' << b << " = " ;
while(a > 1){
int k = b / a + 1;
std::cout << 1 << "/" << k << " + ";
a = a * k - b;
b = b * k;
int r = std::__gcd(a , b);
if(r > 1){ // 约分 , 两个数不互质
a /= r;
b /= r;
}
}
std::cout << a << "/" << b << '\n';
}
int main(){
std::ios::sync_with_stdio(0);
std::cin.tie(0);
std::cout.tie(0);
solved();
return 0;
}