LOJ#10022. 埃及分数【搜索+剪枝】

题目描述 https://loj.ac/problem/10022
这是一个因gcd打错而耽误的题。
这个题要枚举的是有多少个分数,迭代加深搜索!!

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
ll a,b,c[210000],sg[210000];
int maxn,tt=99999;
ll gcd(ll a,ll b)
{
	if(b==0) return a;
	else return gcd(b,a%b);
}
ll mi(ll a,ll b)
{
	for(int i=2;;i++)
	  if(b<=a*i) return i;
}
bool jud(int dp)
{
	if(maxn>tt) return 0;
	if(sg[maxn]>c[tt]) return 0;
	return 1;
}
bool dfs(int d,ll minx,ll x,ll y)//层数 最小层数 分子 分母 
{
	if(d==maxn) 
	{
		if(y%x!=0) return 0;
		sg[d]=y/x;//商
		if(jud(d))
		{
			for(int i=1;i<=maxn;i++) c[i]=sg[i];
			tt=maxn;
		}
		return 1;
	}
	minx=max(minx,mi(x,y));
	bool  fl=0;
	for(int i=minx;i;i++)
	{
		if((maxn-d+1)*y<=i*x) break;
		sg[d]=i;
		ll xx=x*i-y,yy=y*i,ggcd=gcd(xx,yy);
		if(dfs(d+1,i+1,xx/ggcd,yy/ggcd)) fl=1;
	}
	return fl;
}
int main() 
{  
   scanf("%lld%lld",&a,&b);
   if(b%a==0)
   {
   	   printf("%lld",b/a);
   	   return 0;
   }
   ll minn=mi(a,b);//找最小层数 
   maxn=2;
   do
   {
   	   memset(c,63,sizeof(c));
   	   if(dfs(1,minn,a,b)==1)
   	   {
   	       for(int i=1;i<=maxn;i++) printf("%d ",c[i]);
		   return 0;	
	   }
	   maxn++;
   }while(maxn);
   
  return 0;	
}

猜你喜欢

转载自blog.csdn.net/qq_42920122/article/details/88534030