埃及分数题解

想当年,全部人都在评论区里刷我的名字~

ε=(´ο`*)))唉
泪,奔涌

不过为了帮助广大群众,我还是选择写了这份题解……

题目不想说了……

代码如下:

#include<bits/stdc++.h>
#define P pair<LL,LL>
#define f(x) x.first
#define s(x) x.second
#define mp(x,y) make_pair(x,y)
#define LL long long
using namespace std;
LL deepth;//单位分数个数
LL a,b,ans[10001],h[10001],db=10000000;
bool flag;
LL gcd(LL a,LL b){//最大公约数
return b==0?a:gcd(b,a%b);
}
void yf(P &x){//约分
LL g=gcd(f(x),s(x));
f(x)/=g;s(x)/=g;
}
P operator -(P a,P b){//分数减法
LL g=gcd(s(a),s(b));
P c;
f(c)=f(a)*s(b)/g-f(b)*s(a)/g;
s(c)=s(a)*s(b)/g;
yf(c);
return c;
}
P operator /(P a,LL b){//分数除一个整数(用于算分数的平均数)
P c=a;
s(c)*=b;
yf(c);
return c;
}
bool operator >(P a,P b){//分数判断大小
LL g=gcd(s(a),s(b));
return (f(a)*s(b))>(f(b)*s(a));
}
void dfs(LL t,P tmp){//当前正在搜第t个单位分数,剩下的单位分数的和为tmp
yf(tmp);
if(t==deepth){
if(f(tmp)==1&&s(tmp)<db&&s(tmp)>h[t-1]){
//满足条件且结果更优(即最后一个单位分数分母最小)
flag=1;
//搜到结果的标记
db=s(tmp);
for(LL j=1;j<=t-1;j++)
{
ans[j]=h[j];

}
ans[t]=s(tmp);
//记录当前结果
}
return;
}
//以下为枚举当前单位分数的分母
LL j=h[t-1]+1;//这样保证了分母的递增
P bj=tmp/(deepth-t+1);//剩余的单位分数的平均值
while(mp(1,j)>tmp)j++;
//保证当前的单位分数不超过剩余的单位分数的和
for(j=j;mp(1,j)>bj;j++){
//这里都是合法的情况,就搜下去
h[t]=j;
dfs(t+1,tmp-mp(1,j));
}
}
int main(){
freopen("fenshu.in","r",stdin);
freopen("fenshu.out","w",stdout);
cin>>a>>b;
P s=mp(a,b);
yf(s);
if(f(s)==1){//特判它本身就是单位分数
cout<<s(s);
return 0;
}
for(deepth=1;;deepth++){//枚举深度
h[0]=1;
dfs(1,s);
if(flag){//已经找到结果
cout<<ans[1];
for(LL i=2;i<=deepth;i++)
cout<<" "<<ans[i];
return 0;
}
}
return 0;
}

注释就在里面,希望对广大群众有帮助~~~

posted @ 2020-03-27 14:08  nhflsoiers  阅读(196)  评论(0)    收藏  举报