埃及分数

#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;
}
posted @ 2019-05-20 20:40  ShineEternal  阅读(398)  评论(0编辑  收藏  举报