【Codevs1288】埃及分数
Position:
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
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 register
using 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 register
using 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 分数分解
【Codevs1288】埃及分数的更多相关文章
- codevs1288 埃及分数(IDA*)
1288 埃及分数 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 在古埃及,人们使用单位分数的和(形如1/a的 ...
- CodeVS1288埃及分数(IDA*)
在古埃及,人们使用单位分数的和(形如1/a的, a是自然数)表示一切有理数. 如:2/3=1/2+1/6,但不允许2/3=1/3+1/3,因为加数中有相同的. 对于一个分数a/b,表示方法有很多种,但 ...
- codevs1288 埃及分数
题目描述: 在古埃及,人们使用单位分数的和(形如1/a的, a是自然数)表示一切有理数. 如:2/3=1/2+1/6,但不允许2/3=1/3+1/3,因为加数中有相同的. 对于一个分数a/b,表示方法 ...
- 华为OJ平台——将真分数分解为埃及分数
题目描述: 分子为1的分数称为埃及分数.现输入一个真分数(分子比分母小的分数,叫做真分数),请将该分数分解为埃及分数.如:8/11 = 1/2+1/5+1/55+1/110. 输入: 输入一个真分数, ...
- 埃及分数&&The Rotation Game&&骑士精神——IDA*
IDA*:非常好用的搜索,可以解决很多深度浅,但是规模大的搜索问题. 估价函数设计思路:观察一步最多能向答案靠近多少. 埃及分数 题目大意: 给出一个分数,由分子a 和分母b 构成,现在要你分解成一系 ...
- UVA12558 Egyptian Fractions (HARD version)(埃及分数)
传送门 题目大意 给出一个真分数 a/b,要求出几个互不相同的埃及分数(从大到小),使得它们之和为 a/b (埃及分数意思是分子为1的分数,详见百度百科) 如果有多组解,则分数数量少的优先 如果分数数 ...
- 埃及分数问题_迭代加深搜索_C++
一.题目背景 http://codevs.cn/problem/1288/ 给出一个真分数,求用最少的1/a形式的分数表示出这个真分数,在数量相同的情况下保证最小的分数最大,且每个分数不同. 如 19 ...
- Vijos 1308 埃及分数(迭代加深搜索)
题意: 输入a.b, 求a/b 可以由多少个埃及分数组成. 埃及分数是形如1/a , a是自然数的分数. 如2/3 = 1/2 + 1/6, 但埃及分数中不允许有相同的 ,如不可以2/3 = 1/3 ...
- JDOJ 1770 埃及分数
JDOJ 1770: 埃及分数 https://neooj.com/oldoj/problem.php?id=1770 Description 分子均为1的分数叫做埃及分数,因为古代埃及人在进行分数运 ...
- 一本通例题埃及分数—题解&&深搜的剪枝技巧总结
一.简述: 众所周知,深搜(深度优先搜索)的时间复杂度在不加任何优化的情况下是非常慢的,一般都是指数级别的时间复杂度,在题目严格的时间限制下难以通过.所以大多数搜索算法都需要优化.形象地看,搜索的优化 ...
随机推荐
- 安卓app测试之内存分析
一.内存分析步骤 1.启动App. 2.使用monitor命令打开:ADM(包含DDMS) ->update heap 3.操作app,点几次GC 4.dump heap 5.hprof-con ...
- jmeter 常见问题一(url重定向)
刚接触JMeter,想把学习过程中遇到的一些问题,记录下来因为是新接触,所以很多东西都在摸索中! 使用Badboy录制了公司一个项目的登录功能导入到JMeter后,执行场景,发现登录校验成功,但后续的 ...
- Nginx 通过 certbot 为网站自动配置 SSL 证书并续期
一.背景知识 1.1.http 和 https 是什么? 简单来说,http 是一个传输网页内容的协议,比如你看到的 http 开头的网站 http://www.163.com ,其网页上的文字.图片 ...
- 少啰嗦!一分钟带你读懂Java的NIO和经典IO的区别
1.引言 很多初涉网络编程的程序员,在研究Java NIO(即异步IO)和经典IO(也就是常说的阻塞式IO)的API时,很快就会发现一个问题:我什么时候应该使用经典IO,什么时候应该使用NIO? 在本 ...
- java虚拟机(五)--垃圾回收机制GC5
什么样的对象需要回收 如果对象已经死亡了,就可以进行回收,判断方式如下 1).引用计数器:给对象添加一个计数器,有地方引用,就+1,当引用失效,就-1.当计数器为0时,判断对象不能再使用,但是当对象相 ...
- ThinkPHP---案例2--部门管理功能
[一]部门列表展示 分析: ①控制器DeptController.class.php ②方法showList(不要使用list方法,因为list是关键词) ③模板文件:showList.html 下面 ...
- git学习(3)----git 新建分支并提交本地代码到远程分支
一.步骤 1.在gitlab上创建一个issue,issue一般来说是版本发布说明.比如本次更新了什么功能,修复了什么bug什么的. 2.然后在本地创建一个branch,或者直接在gitlab上申请m ...
- Jmeter逻辑控制器-ForEach Controller
ForEach Controller 介绍 ForEach Contoller 即循环控制器,顾名思义是定义一个规则.主要有以下一个参数: 名称:随便填写 注释:随便填写 输入变量前缀:可以在&quo ...
- 谈谈TCP中的TIME_WAIT
所以,本文也来凑个热闹,来谈谈TIME_WAIT. 为什么要有TIME_WAIT? TIME_WAIT是TCP主动关闭连接一方的一个状态,TCP断开连接的时序图如下: 当主动断开连接的一方(Initi ...
- 第十四节:Web爬虫之Ajax数据爬取
有时候在爬取数据的时候我们需要手动向上滑一下,网页才加载一定量的数据,但是网页的url并没有发生变化,这时我们就要考虑使用ajax进行数据爬取了...