|
推荐
楼主 |
发表于 2018-5-12 23:40:52
|
只看该作者
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- using namespace std;
- const int MAXN=20000;
- long long maxd;
- long long v[MAXN],ans[MAXN];///v是暂时存放的满足题意的分母的数组,ans是记录满足题意的最优分母值的数组。
- long long gcd(long long a,long long b)///求最大公约数
- {
- long long m;
- while(a!=0)
- {
- m=b%a;
- b=a;
- a=m;
- }
- return b;
- }
- long long getfirst(long long a,long long b)///取比a/b小的最大分数,分子必须为1
- {
- long long i,j;
- for(i=2;;i++)
- {
- if(b<a*i)
- {
- break;
- }
- }
- return i;
- }
- bool better(long long d)///必要的判断,这组分数之和是否满足最优解
- {
- long long i;
- bool flag=true;
- if(ans[d]==-1)///由于初始化ans是-1,如果是第一次出现的满足题意的解,返回true
- return true;
- for(i=d;i>=0;i--)
- {
- if(v[i]==ans[i])///从高位进行判断大小,题意要求
- continue;
- else if(v[i]>ans[i])
- {
- //return false;
- flag=false;
- break;
- }
- else
- {
- break;
- }
- }
- return flag;
- }
- bool dfs(long long a,long long b,long long from,long long d)//深度为d
- {
- long long aa,bb,g,i;
- bool ok;
- // cout<<from<<endl;
- if(d==maxd)
- {
- if(a!=1)
- return false;
- for(i=0;i<=d-1;i++)
- {
- if(v[i]==b)
- {
- return false;
- }
- }
- v[d]=b;
- sort(v,v+d);
- if(better(d))
- memcpy(ans,v,sizeof(long long)*(d+1));
- return true;
- }
- ok=false;
- //重要!!!
- from=max(from,getfirst(a,b));///枚举起点,去上一次加一的分母值和比a/b小的最大分数的分母中更大的。
- for(i=from;;i++)
- {
- ///剪枝,如果c/d(前i个分数之和)+1/e*(maxd-i)<a/b,可以直接break;
- if(b*(maxd+1-d)<=a*i)
- break;
- v[d]=i;
- aa=a*i-b;
- bb=b*i;
- g=gcd(aa,bb);
- aa=aa/g;
- bb=bb/g;///约分
- if(dfs(aa,bb,i+1,d+1))
- ok=true;
- }
- return ok;
- }
- int main()
- {
- long long a,b,aa,bb,i,g;
- while(cin>>a>>b)
- {
- if(a==0)
- {
- cout<<a<<"/"<<b<<"=0"<<endl;
- continue;
- }
- memset(ans,-1,sizeof(ans));
- g=gcd(a,b);
- aa=a/g;
- bb=b/g;
- if(aa==1)
- {
- printf("%d/%d=%d/%d\n",a,b,aa,bb);
- }
- else
- {
- for(maxd=1;;maxd++)
- {
- if(dfs(aa,bb,getfirst(aa,bb),0))
- break;
- }
- cout<<a<<"/"<<b<<"=";
- for(i=0;i<=maxd-1;i++)
- cout<<"1/"<<ans[i]<<"+";
- cout<<"1/"<<ans[i];
- cout<<endl;
- }
- }
- return 0;
- }
复制代码 |
|