其他分享
首页 > 其他分享> > 埃及分数

埃及分数

作者:互联网

#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;
}

标签:分数,埃及,cnt,return,gcd,long,print,tmp
来源: https://www.cnblogs.com/ShineEternal/p/10896319.html