具体约束:

给定一个小数x,x满足0<=x<1,且保证给定的x保留了18位小数

输出一个分数,使得分母不超过1e9,分子分母互质,且在满足这些条件的情况下最接近x

了解一下法雷数列和stern-brocot tree (某种意义上他们是在描述一个东西)

https://en.wikipedia.org/wiki/Stern%E2%80%93Brocot_tree

然后考虑在这个树上二分答案的上下界(个人觉得也可以叫伪二分),

一层一层的下降,时间复杂度O(q), q为限制分母大小,本题中为1e9,不行

考虑加速,我们在一次二分过程结束后,上下界由 [l, r] 变为 [l, mid] 或 [mid, r]

但是实际上如果左边界一开始就非常贴近答案,那么我们连续下降很多次的过程中都是将 r 变为 (l + r) / 2

这样是很傻的,所以我们每次考虑下降多次,并且仍然满足条件即可

至于每次下降多少层,就二分一下就可以了

复杂度感觉不太直观,个人感觉是log^2(不负责猜测),不然1w组数据,log的复杂度python不应该2s跑不出

python代码

 inf, inff = 10 ** 9, 10 ** 18
for i in range(int(input())):
n = int(input()[2:])
if n == 0: print('0 1')
else:
lp, lq, rp, rq = 0, 1, 1, 1
while max(lq, rq) <= inf:
mp, mq = lp + rp, lq + rq
if mp * inff <= mq * n:
l, r, mid, cnt = 1, (inf - lq) // rq + 1, -1, -1
while l <= r:
mid = l + r >> 1
if (lp + rp * mid) * inff <= (lq + rq * mid) * n:
cnt, l = mid, mid + 1
else:
r = mid - 1
lp, lq = lp + rp * cnt, lq + rq * cnt
else:
l, r, mid, cnt = 1, (inf - rq) // lq + 1, -1, -1
while l <= r:
mid = l + r >> 1
if (rp + lp * mid) * inff > (rq + lq * mid) * n:
cnt, l = mid, mid + 1
else:
r = mid - 1
rp, rq = rp + lp * cnt, rq + lq * cnt
if lq <= inf: print(lp, lq)
else: print(rp, rq)

拓展应用:

问题:给定小数,求出分数p/q,满足p/q>x, q<=1e9,且p/q-x最小

解法:其实是同一个问题,同样是求上下界

问题: 给出abcd四个整数,保证a/b<c/d,求出pq两个整数,使得a/b<p/q<c/d且q最小

解法: 如果abs(ad - bc) == 1,那么a/b和c/d两个分数再某阶法雷序列里是相邻的,就有p=a+c, q=b+d

否则我们很容易有一个O(max(b,d))的做法,从上到下,求出两个分数每层的上下界

需要注意对a/b求的上下界是[l, r), 对c/d求的上下界是(l, r]

     然后当某一层a/b的上界==c/d的下界的时候,这个分数就是p/q了

考虑一下这个东西同样是可以加速的,a/b的下界和c/d的上界我们是不关心的,加速方法同上

然后考虑加速a/b的上界r1和c/d的下界l2,我们非常关注他们第一次分开的时候

也就是最早满足r1 <= l2的时候,所以这个也是二分

至此我们就解决了这个问题,时间复杂度和上面是相同的!

小数化分数的O(log2n)解法的更多相关文章

  1. HDU1717小数化分数2

    小数化分数2 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  2. 【HDU】1717 小数化分数2 ——计数原理

    小数化分数2 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  3. HDU 1717 小数化分数2(最大公约数)

    小数化分数2 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  4. 紫书 习题8-14 UVa 1616(二分+小数化分数+精度)

    参考了https://www.cnblogs.com/dwtfukgv/p/5645446.html (1)直接二分答案.说实话我没有想到, 一开始以为是贪心, 以某种策略能得到最优解. 但是想了很久 ...

  5. CSU 8月月赛 Decimal 小数化分数

    http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1303 这个OJ很容易跪所以我贴一下题目 Description 任意一个分数都是有理数,对于任意一 ...

  6. 杭电oj1717——小数化分数(java实现)

    question:小数化分数2 思路: /** * 这道题没有整数部分(有也无所谓,算小数部分,算完了分子分母按倍数加上就好),也就是说数组直接从a[2]开始后面是小数,我把这道题分为了三类: * * ...

  7. HDU 1717 小数化分数2 数学题

    解题报告:输入一个小于1的小数,让你把这个数转化成分数,但注意,输入的数据还有无限循环的小数,循环节用一对括号包含起来. 之前还没有写过小数转分数的题,当然如果没有循环小数的话,应该比较简单,但是这题 ...

  8. ACM学习历程—HDU1717 小数化分数2(gcd)

    Description Ray 在数学课上听老师说,任何小数都能表示成分数的形式,他开始了化了起来,很快他就完成了,但他又想到一个问题,如何把一个循环小数化成分数呢? 请你写一个程序不但可以将普通小数 ...

  9. hdu 1905 小数化分数2

    ;}

随机推荐

  1. bzoj 1616: [Usaco2008 Mar]Cow Travelling游荡的奶牛【dp】

    写了个bfs发现MLE了... 设f[t][i][j]为在t时刻走到(i,j)的方案数,转移和bfs一样 #include<iostream> #include<cstdio> ...

  2. 讯搜问题排查xunsearch

    mysql导入数据不成功,开始重建索引后提示 [XSException] ../local/xunsearch/sdk/php/lib/XS.php(1898): DB- 可打印的版本 开始重建索引 ...

  3. 二分搜索 POJ 2456 Aggressive cows

    题目传送门 /* 二分搜索:搜索安排最近牛的距离不小于d */ #include <cstdio> #include <algorithm> #include <cmat ...

  4. Windows Server 2008 R2关闭FTP服务

    公司在ZJ的项目给了一台互联网可以访问的测试服务器,但是只给了三个访问端口,而且还做了映射. 映射信息如下:[1050->3389,1051->50000,1053->21] 其中1 ...

  5. 299 Bulls and Cows 猜数字游戏

    你正在和你的朋友玩猜数字(Bulls and Cows)游戏:你写下一个数字让你的朋友猜.每次他猜测后,你给他一个提示,告诉他有多少位数字和确切位置都猜对了(称为”Bulls“, 公牛),有多少位数字 ...

  6. [转]Paging, Searching and Sorting in ASP.Net MVC 5

    本文转自:http://www.c-sharpcorner.com/UploadFile/4b0136/perform-paging-searching-sorting-in-Asp-Net-mvc- ...

  7. Asp.net:MVC认识

    用MVC框架好长一段时间,发现每天都是写业务代码,不想每天只为了工作而写代码,想把工作中认识的MVC框架,遇到的问题,有时候天天在用,但是不知道里面是什么东西,什么原理,为啥這样写等一系列问题.进行梳 ...

  8. .Net MVC 与WebApi ActionFilterAttribute 区别

    首先我们来看下 这两个ActionFilterAttribute 的命名空间区别的: 可以看出mvc 引用的是System.Web.Mvc,webapi 引用的是System.Web.Http.Fil ...

  9. NodeJs学习记录(五)初学阶段关于ejs和路由

    1.因为只是用了一点皮毛,所以使用起来感觉基本和jsp无异, 逻辑代码块使用  <%  if() {} else  %> , 输出参数值使用 <%=title  %>, 有一个 ...

  10. Spark学习之RDD编程(2)

    Spark学习之RDD编程(2) 1. Spark中的RDD是一个不可变的分布式对象集合. 2. 在Spark中数据的操作不外乎创建RDD.转化已有的RDD以及调用RDD操作进行求值. 3. 创建RD ...