Best Rational Approximation UVALive - 8292

题目链接

这道题难住我们的是小数位数,然而。。。小数位数好像不需要考虑,可是题目给出的小数部分由20位啊,double不是15还是16位吗,不会有误差吗,有知道的大神求告知。百度题解时看到了法里数列这个字眼,然后就只去百度了法里数列

百度百科:

       法里数列是以英国地质学家老约翰·法里得名,他关于这数列的信刊登在1816年的《哲学杂志》。法里猜测这数列的每一项都是相邻两项的中间分数;不过,以所知道的资料,他没有证明这个性质。法里的信给柯西读了,就给了一个证明在他的《数学习题》,把这结果归到法里上。其实,另一位数学家 C. Haros 曾在1802年发表了相类似的结果,几乎可以肯定法里和柯西都没看过。所以,法里的名字给了这个数列,是历史的一次意外。

我觉得最重要的一句话,红色标出了,就是这个意思

0/1    1/1

0/1     1/2     1/1

0/1     1/3      2/3    1/1..

中间产生的分数的分母是前一项与后一项的分母之和,同理分子是前一项与后一项的分子之和。

然后这道题用二分法,最后比一下两个分数的小数部分那个更接近题目所给的那个小数

#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <cstring>
#include <sstream>
#include <cmath>
#include <stack>
#include <map>
#define ll long long
#define ull unsigned long long
#define INF 0x3f3f3f3f
#define mod 1000000007;
using namespace std;

int main()
{
    int t,k,m;
    double p;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%lf",&k,&m,&p);
        int x1 = 0,y1 = 1,x3 = 1,y3 = 1;
        while(1)
        {
            int x2 = x1 + x3,y2 = y1 + y3;
            if(y2 > m) break;
            if(x2 * 1.0 / y2 <= p)
            {
                x1 = x2;
                y1 = y2;
            }
            else
            {
                x3 = x2;
                y3 = y2;
            }
        }
        printf("%d ",k);
        if(fabs(x1 * 1.0 / y1 - p) > fabs(x3 * 1.0 / y3 - p))
            printf("%d/%d\n",x3,y3);
        else printf("%d/%d\n",x1,y1);
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值