Codevs 1288 埃及分数
来源:互联网 发布:网络ms是什么意思啊 编辑:程序博客网 时间:2024/05/23 22:24
Codevs 1288 埃及分数
Position:
- http://codevs.cn/problem/1288/
List
- Codevs 1288 埃及分数
- List
- Description
- Input
- Output
- Sample Input
- Sample Output
- Solution
- 精简版本
- Source
- Code
- Codevs这个
- Source
- Code
- 原型
- 精简版本
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
Input
a b
Output
若干个数,自小到大排列,依次是单位分数的分母。
Sample Input
19 45
Sample Output
5 6 18
Solution
精简版本
给定一个分数 A/B,要将其转换为单位分数之和。要求单位分数数量最少,且每个分数都不同。
Source
普通搜索枚举哪个数可以填显然会TLE,它会不断搜下去,爆LL,爆栈。
那么怎么解决呢?采用迭代加深算法,限定分成的数目,如果当前可以,即为最小输出方案即可。
剪枝(见check函数):当前可以搜的最大分数(由分数从大到小搜索)×剩余块数<还要搞的分数,就可以return了,因为之后不可能有解。
Code
// <math.cpp> - Wed Sep 28 08:14:53 2016// This file is made by YJinpeng,created by XuYike's black technology automatically.// Copyright (C) 2016 ChangJun High School, Inc.// I don't know what this program is.#include <iostream>#include <algorithm>#include <cstdio>#include <cstdlib>#include <cmath>#define IN inline#define RG registerusing namespace std;typedef long long LL;const int MAXN=100010;const int MAXM=100010;inline LL gi() { register LL w=0,q=0;register char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')q=1,ch=getchar(); while(ch>='0'&&ch<='9')w=w*10+ch-'0',ch=getchar(); return q?-w:w;}int n;LL as[MAXN];IN bool check(LL a,LL b,LL c,LL d){ if(a*d>b*c)return 0; else return true;}IN void dfs(LL x,LL y,LL f,int d){ if(x<0)return; if(d==1){ if(x==1&&y>=f){ printf("%d\n",n); for(int i=n;i>=2;i--) printf("%lld ",as[i]); printf("%lld",y);exit(0); } return; } for(RG LL i=f,g;check(x,y,d,i);i++){ as[d]=i;g=__gcd(x*i-y,y*i); dfs((x*i-y)/g,y*i/g,i+1,d-1); }}int main(){ freopen("math.in","r",stdin); freopen("math.out","w",stdout); int x=gi(),y=gi(); for(int i=1;;i++)n=i,dfs(x,y,1,i); return 0;}
Codevs这个
注意这题和上面那道普通题不同:加数个数相同的,最小的分数越大越好。
Source
最后统计答案时,不直接exit(0);让它将这一层(迭代的深度)全搜完,统计最优答案。
Code
// <math.cpp> - Wed Sep 28 08:14:53 2016// This file is made by YJinpeng,created by XuYike's black technology automatically.// Copyright (C) 2016 ChangJun High School, Inc.// I don't know what this program is.#include <iostream>#include <algorithm>#include <cstdio>#include <cstdlib>#include <cmath>#define IN inline#define RG registerusing namespace std;typedef long long LL;const int MAXN=100010;const int MAXM=100010;inline LL gi() { register LL w=0,q=0;register char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')q=1,ch=getchar(); while(ch>='0'&&ch<='9')w=w*10+ch-'0',ch=getchar(); return q?-w:w;}int n;LL as[MAXN],sa[MAXN];bool flag;IN bool check(LL a,LL b,LL c,LL d){ if(a*d>b*c)return 0; else return true;}IN void dfs(LL x,LL y,LL f,int d){ if(x<0)return; if(d==1){ if(x==1&&y>=f){ if(y<sa[1]){ flag=true;sa[1]=y; for(int i=n;i>=2;i--)sa[i]=as[i]; } } return; } for(RG LL i=f,g;check(x,y,d,i);i++){ as[d]=i;g=__gcd(x*i-y,y*i); dfs((x*i-y)/g,y*i/g,i+1,d-1); }}int main(){ freopen("math.in","r",stdin); freopen("math.out","w",stdout); int x=gi(),y=gi();flag=false;sa[1]=1e17; for(int i=1;;i++){ n=i,dfs(x,y,1,i); if(flag){ for(int i=n;i;i--)printf("%lld ",sa[i]);return 0; } } return 0;}
原型
参考我的博客:SWUST626 分数分解
0 0
- codevs 1288 埃及分数
- CODEVS 1288 埃及分数
- Codevs 1288 埃及分数
- Codevs 1288 埃及分数 【IDA*】
- Codevs P1288 埃及分数
- [codevs 1288] 埃及分数 [IDdfs 迭代加深搜索 ]
- Codevs 1288 埃及分数(迭代加深搜索)
- codevs 1288 埃及分数 迭代加深搜索
- 1288 埃及分数
- 【codevs 1288】【vijos P1308】埃及分数(迭代加深搜)
- CODE[VS] 1288 埃及分数
- 埃及分数
- 埃及分数
- 埃及分数
- 埃及分数
- 埃及分数
- 埃及分数
- 埃及分数
- Spinner
- 面试题——不用循环计算1+2+...+100之和
- 我的自白书
- RequireJs使用
- (并查集)Ubiquitous Religions
- Codevs 1288 埃及分数
- 转载《Oracle中NUMBER类型问题 》
- Linux平台下Python脚本编程入门(一)
- spring 控制反转
- 排查Full GC
- Apk反编译之晋江小说阅读
- Oracle11g无法登录DatabaseControl浏览器
- Hive学习笔记 --- 深入理解 HIVE 个各种存储模式
- 自定义控件其实很简单7/12