codevs 1288 埃及分数
2016-09-04 23:03
387 查看
时间限制: 1 s
空间限制: 128000 KB
题目描述 Description
在古埃及,人们使用单位分数的和(形如1/a的, a是自然数)表示一切有理数。 如:2/3=1/2+1/6,但不允许2/3=1/3+1/3,因为加数中有相同的。 对于一个分数a/b,表示方法有很多种,但是哪种最好呢? 首先,加数少的比加数多的好,其次,加数个数相同的,最小的分数越大越 好。 如: 19/45=1/3 + 1/12 + 1/180 19/45=1/3 + 1/15 + 1/45 19/45=1/3 + 1/18 + 1/30, 19/45=1/4 + 1/6 + 1/180 19/45=1/5 + 1/6 + 1/18. 最好的是最后一种,因为1/18比1/180,1/45,1/30,1/180都大。
给出a,b(0 < a < b < 1000),编程计算最好的表达方式。
输入描述 Input Description
a b
输出描述 Output Description
若干个数,自小到大排列,依次是单位分数的分母。
样例输入 Sample Input
19 45
样例输出 Sample Output
5 6 18
【分析】
题目好理解,做起来如同日狗。
第一道迭代加深搜索。
根据题目要求:加数越少越好,所以用迭代加深。
具体解释程序中有注释哒。
【代码】
空间限制: 128000 KB
题目描述 Description
在古埃及,人们使用单位分数的和(形如1/a的, a是自然数)表示一切有理数。 如:2/3=1/2+1/6,但不允许2/3=1/3+1/3,因为加数中有相同的。 对于一个分数a/b,表示方法有很多种,但是哪种最好呢? 首先,加数少的比加数多的好,其次,加数个数相同的,最小的分数越大越 好。 如: 19/45=1/3 + 1/12 + 1/180 19/45=1/3 + 1/15 + 1/45 19/45=1/3 + 1/18 + 1/30, 19/45=1/4 + 1/6 + 1/180 19/45=1/5 + 1/6 + 1/18. 最好的是最后一种,因为1/18比1/180,1/45,1/30,1/180都大。
给出a,b(0 < a < b < 1000),编程计算最好的表达方式。
输入描述 Input Description
a b
输出描述 Output Description
若干个数,自小到大排列,依次是单位分数的分母。
样例输入 Sample Input
19 45
样例输出 Sample Output
5 6 18
【分析】
题目好理解,做起来如同日狗。
第一道迭代加深搜索。
根据题目要求:加数越少越好,所以用迭代加深。
具体解释程序中有注释哒。
【代码】
//codevs 1288 埃及分数 #include<iostream> #include<cstdio> #include<cstring> #define ll long long #define mxn 2147483647 #define fo(i,j,k) for(long long i=j;i<=k;i++) using namespace std; int k; ll a,b; bool czy; ll ans[20],v[20]; inline ll gcd(ll x,ll y) //以下两个函数不用多解释 { if(x%y==0) return y; return gcd(y,x%y); } inline bool yue(ll x,ll y) { ll c=gcd(y,x); x=x/c,y=y/c; if(x==1) return 1; return 0; } inline void dfs(int dep,ll aa,ll bb) { if(dep==k) //满足层数后进行判断 { if(bb%aa!=0) return; v[k]=bb/aa; if(v[k]!=v[k-1] && v[k]<ans[k]) { fo(i,1,k) ans[i]=v[i]; czy=1; } return; } ll low=max(v[dep-1]+1,bb/aa); //下界满足两个条件:比上一个大且不超过当前数字。 ll high=bb*(k-dep+1)/aa; //上界条件:如果剩下所有分数都是这个数,能凑齐当前数字 if(high>mxn) high=mxn; //不要超过int范围,要不太浮夸 if(k && bb/aa+k-dep+1>=ans[k]) return; //如果最后的最优数字比当前最优解大,跳出 fo(i,low,high) { v[dep]=i; ll fi=aa*i-bb,se=bb*i; //这步是计算当前数字-1/i后所得到的答案 if(fi<=0 || se<=0) continue; //防止出现玄学RE问题 yue(fi,se); dfs(dep+1,fi,se); } } int main() { scanf("%lld%lld",&a,&b); if(yue(a,b)) { printf("%lld\n",b); return 0; } for(k=2;k<=13;k++) { memset(ans,0x3f,sizeof ans); v[0]=0; dfs(1,a,b); if(czy) { fo(i,1,k) printf("%lld ",ans[i]); printf("\n"); return 0; } } return 0; }
相关文章推荐
- codevs1288 埃及分数
- 【基础练习】【IDA*】codevs1288 埃及分数题解
- 【Codevs1288】埃及分数
- [迭代加深搜索] Codevs1288 埃及分数问题
- codevs 1288 埃及分数 迭代加深搜索
- [codevs1288]埃及分数(迭代加深搜索)
- 埃及分数(codevs 1288)
- Codevs 1288 埃及分数 【IDA*】
- Codevs 1288 埃及分数
- CODE[VS] 1288 埃及分数
- 搜索+剪枝——CODEVS1288 埃及分数
- [codevs1288]埃及分数 迭代加深搜索
- [CODEVS1288]埃及分数(迭代加深搜索)
- Codevs P1288 埃及分数
- codevs1288埃及分数-迭代加深搜索
- [CODEVS1225]埃及分数解题报告
- 1288 埃及分数
- codevs1288 埃及分数(IDA*)
- 1288 埃及分数
- [CodeVS 1288] 埃及分数:IDA*