传送门

题目大意

给出一个真分数 a/b,要求出几个互不相同的埃及分数(从大到小),使得它们之和为 a/b

(埃及分数意思是分子为1的分数,详见百度百科

如果有多组解,则分数数量少的优先

如果分数数量一样则分母最大的要尽量小,如果最大的分母同样大,则第二大的分母尽量小,以此类推

为了加大难度,会给出k个不能作为分母的数

(2<=a,b<=876,k<=5 并且 a,b 互质)

首先想的是数论,但是呢

推不出来...

然后发现a,b好像不大

貌似可以搜索

但是呢

不知道上界...

那就迭代加深搜索呗

然后想想怎么剪枝

如果知道 a/b,要怎么求出最小 k 使 1/k < a/b 呢(注意符号)

易知 a/b 为真分数 ,a,b,k均为整数
所以 a<b
所以必定有整数 x,y 使得 x*a+y=b 且y<a
所以可得 int(b/a)=int( (x*a+y) /a )=int(x*a/a)+int(y/a) = x
因为 int(b/a)<=b/a,int(b/a)=x
所以 x+ > b/a , 所以 int(b/a)+1>b/a,
所以1/(x+) < a/b 又 /int(b/a)=/x >=a/b 所以 x+1就是最小的 k 使得 /k < a/b 所以 k=int(b/a) +  证明完毕

知道了 k 的下界,那还要求 k 的上界

显然每次求的分母肯定要比上一次大(题目要求)

所以如果后面所有的分母都为 k ,加起来还没有当前要求的数大,那就不要再搜下去了,再下去也不会有结果的

然后就可以搜了,至于判断是否可用我用的是set

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<set>
using namespace std;
const int N=1e5+;
set <long long> p;
long long t,A,B,n,mxdep;
long long ans[N],w[N];
bool flag;
inline long long gcd(long long a,long long b)
{
return b ? gcd(b,a%b) : a;
}//gcd是为了约分
inline bool pd()
{
for(int i=mxdep;i;i--)
if(ans[i]!=w[i])
return ans[i]&&ans[i]<w[i];
return ;
}//判断答案是否更优
inline void dfs(long long dep,long long a,long long b,long long mi)
{
if(dep==mxdep)
{
if(b%a||(b<(mi-)*a+)||p.count(b/a)) return;//判断合法性
//如果a/b可化为 1/k 的形式并且 1/k 可以选
w[dep]=b/a;
if(pd()) return;//判断答案是否更优
memcpy(ans,w,sizeof(w)); flag=;//更新
return;
}
mi=max(mi,b/a+);//求出下界
for(long long i=mi;i;i++)
{
if( (mxdep-dep+)*b<=i*a ) return;//上界
if(p.count(i)) continue;//判断合法
w[dep]=i;//记录路径
long long xa=a*i-b,xb=i*b;//通分
long long z=gcd(xa,xb);
dfs(dep+,xa/z,xb/z,i+);//约分,向下一层
}
}
int main()
{
cin>>t;
for(long long i=;i<=t;i++)
{
flag=; mxdep=;
cin>>A>>B>>n;
long long c;
p.clear();//细节
while(n--) scanf("%lld",&c),p.insert(c);//存储不合法的数
while(mxdep++)
{
memset(ans,,sizeof(ans));
dfs(,A,B,B/A+);
if(flag) break;
}//迭代加深
printf("Case %lld: %lld/%lld=1/%lld",i,A,B,ans[]);
for(int i=;i<=mxdep;i++)
printf("+1/%lld",ans[i]);
printf("\n");
}
return ;
}

UVA12558 Egyptian Fractions (HARD version)(埃及分数)的更多相关文章

  1. UVA12558 Egyptian Fractions (HARD version) (埃及分数,迭代加深搜索)

    UVA12558 Egyptian Fractions (HARD version) 题解 迭代加深搜索,适用于无上界的搜索.每次在一个限定范围中搜索,如果无解再进一步扩大查找范围. 本题中没有分数个 ...

  2. uva12558 Egyptian Fractions (HARD version)(迭代深搜)

    Egyptian Fractions (HARD version) 题解:迭代深搜模板题,因为最小个数,以此为乐观估价函数来迭代深搜,就可以了. #include<cstdio> #inc ...

  3. UVA-12558 Egyptian Fractions (HARD version) (IDA* 或 迭代加深搜索)

    题目大意:经典的埃及分数问题. 代码如下: # include<iostream> # include<cstdio> # include<cstring> # i ...

  4. UVa 12558 - Egyptian Fractions (HARD version)

    题目大意: 给出一个真分数,把它分解成最少的埃及分数的和.同时给出了k个数,不能作为分母出现,要求解的最小的分数的分母尽量大. 分析: 迭代加深搜索,求埃及分数的基础上,加上禁用限制就可以了.具体可以 ...

  5. 【习题 7-7 UVA-12558】Egyptian Fractions (HARD version)

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 迭代加深搜索. 枚举最大量maxdep 在dfs里面传剩余的要凑的分子.分母 以及上一次枚举的值是多少. 然后找到最小的k,满足1/ ...

  6. 【Uva 12558】 Egyptian Fractions (HARD version) (迭代加深搜,IDA*)

    IDA* 就是iterative deepening(迭代深搜)+A*(启发式搜索) 启发式搜索就是设计估价函数进行的搜索(可以减很多枝哦~) 这题... 理论上可以回溯,但是解答树非常恐怖,深度没有 ...

  7. UVA_埃及分数(Hard Version) UVA 12588

    Problem EEg[y]ptian Fractions (HARD version)Given a fraction a/b, write it as a sum of different Egy ...

  8. UVA12558-Efyptian Fractions(HARD version)(迭代加深搜索)

    Problem UVA12558-Efyptian Fractions(HARD version) Accept:187  Submit:3183 Time Limit: 3000 mSec  Pro ...

  9. 华为OJ平台——将真分数分解为埃及分数

    题目描述: 分子为1的分数称为埃及分数.现输入一个真分数(分子比分母小的分数,叫做真分数),请将该分数分解为埃及分数.如:8/11 = 1/2+1/5+1/55+1/110. 输入: 输入一个真分数, ...

随机推荐

  1. Eclipse Maven 编译错误 Dynamic Web Module 3.0 requires Java 1.6 or newer 解决方案

    Eclipse Maven 开发一个 jee 项目时,编译时遇到以下错误:Description Resource Path Location TypeDynamic Web Module 3.0 r ...

  2. 无法解决 equal to 操作中 "Chinese_PRC_CI_AS" 和 "Chinese_PRC_BIN" 之间的排序规则冲

    在两个数据库之间进行复合查询时有时会出现如下错误: 无法解决 equal to 操作中 "Chinese_PRC_CI_AS" 和 "Chinese_PRC_BIN&qu ...

  3. SQl Server T-sql语句学习

    T-sql语句就是通过代码来代替鼠标完成一些操作,使用起来要比鼠标方便很多. 创建数据库   careate  database  +数据库名. 数据库名不能为中文,不能以数字开头. use  数据库 ...

  4. 算法Sedgewick第四版-第1章基础-2.1Elementary Sortss-006归并排序(Mergesort)

    一. 1.特点 (1)merge-sort : to sort an array, divide it into two halves, sort the two halves (recursivel ...

  5. p1129 [ZJOI2007]矩阵游戏

    传送门 分析 不难想到将黑点的行列连边,然后判断最大匹配是否等于n 代码 #include<iostream> #include<cstdio> #include<cst ...

  6. beforeFilter()

    在控制器每个动作之前执行,可以方便地检查有效的会话,或者检查用户的权限. function beforeFilter() { parent::beforeFilter(); if(empty($thi ...

  7. python3-while与continue

    # Auther: Aaron Fan #要返回到循环开头,并根据条件测试结果决定是否继续执行循环,可使用continue#执行continue语句,让python忽略余下的代码 #只打印1到10之间 ...

  8. getBytes()详解.RP

    在java中,getBytes()方法如果不指定字符集,则得到的是一个操作系统默认的编码格式的字节数组:如果指定字符集,则得到的是在指定字符集下的字节数组,如: byte[] b_gbk = &quo ...

  9. 自定义select样式

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  10. Gremlin:图遍历语言

    Gremlin简介 Gremlin是Apache TinkerPop 框架下的图遍历语言.Gremlin是一种函数式数据流语言,可以使得用户使用简洁的方式表述复杂的属性图(property graph ...