埃及分数
#include<cstdio>
#include<iostream>
using namespace std;
long long final[1005],tmp[1005];
long long gcd(long long x,long long y)
{
if(y==0)return x;
return gcd(y,x%y);
}
long long a,b;
void print(long long d)
{
if(final[d]>tmp[d])//限制分母,不能太大
{
for(long long i=1;i<=d;i++)
{
final[i]=tmp[i];
}
}
}
void dfs(long long a,long long b,long long cnt,long long d)
{
if(cnt==d)//达到指定位数
{
tmp[cnt]=b;//记录分母
if(a==1&&tmp[cnt]>tmp[cnt-1])//由于最后一次剩的分母可能小 ,那么就会超出
{
print(d);
}
return ;
}
for(long long i=max(tmp[cnt-1]+1,b/a+1);i<(d-cnt+1)*b/a;i++)
//首先肯定是从b/a+1开始,然后就是肯定要从上一次计算的下一位做分母,否则肯定大了
//循环到剩余位数*b/a
{
long long x=b*i/gcd(b,i);//找上一次的结果分母和这次的i分母的最小公倍数
long long y=x*a/b-x/i;
//原来的分数a/b×这个公倍数,分母b就去掉了,而x/i也就是新+的分数需要同时扩大的倍数
long long qwq=gcd(x,y);
x=x/qwq;
y=y/qwq;//约分
tmp[cnt]=i;
dfs(y,x,cnt+1,d);
}
}
int main()
{
scanf("%lld%lld",&a,&b);
long long ss=gcd(a,b);
a=a/ss;
b=b/ss;
//约分
long long d;
for(d=2;;d++)//枚举分数个数
{
final[1]=0;//长久记录分母的数组
tmp[0]=0;//短暂记录
final[d]=200000001;
dfs(a,b,1,d);
if(final[1]!=0)break; //找到一个就跑
}
for(long long i=1;i<=d;i++)
{
printf("%d ",final[i]);
}
return 0;
}
作者&出处:ShineEternal
本文阅读完毕欢迎到此留言:link
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利.
你看地这么津津有味,不点个赞再走吗QAQ