BUCT-2021年ACM竞赛班训练(六)2021.4.29-问题 C:女神的考验-题解

33 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

@TOC


女神的考验

传送门

时间限制:1秒 空间限制:128M


题目描述

星空点点,墨日曜淡。世界芳华灼灼,不及眼前的她。

你只用了几毫秒就得到了小L想要的答案,小L为此惊叹于计算机的算力,他天真地以为,计算机就是一步一步地计算下去才得到答案的。 不知道上面在说什么请点我

女神会心一笑,甩给小L一道题: 给你一个十进制正数,总共不超过1515位。让你把他转换成a1+1a2+1a3+1a4+1a_1+\frac{1}{a_2+\frac{1}{a_3+\frac{1}{a_4+\frac{1}{\cdots}}}}的形式。 在此,我们只关注a1a2a3a4a_1、a_2、a_3、a_4、\cdots,小L只需要依次回答这些aa即可。

如:1.3125=1+13+151.3125=1+\frac{1}{3+\frac{1}{5}},小L只需要回答1 3 5即可。


输入描述

给你一个十进制的正数nn,其中nn的位数不超过1515(即,小数点前后出现的单个数字的个数之和小于15)


输出描述

你需要把这个数转换成a1+1a2+1a3+1a4+1a_1+\frac{1}{a_2+\frac{1}{a_3+\frac{1}{a_4+\frac{1}{\cdots}}}}的形式,并输出a1 a2 a3  ana_1\ a_2\ a_3\ \cdots\ a_n,它们之间用一个空格隔开。


样例一

输入

1.3125

输出

1 3 5

题目分析

题目给的数据不一定是整数,故可先将小数化为整数:1.3125=1312510000=21161.3125=\frac{13125}{10000}=\frac{21}{16} 然后将假分数化为带分数:2116=1+516\frac{21}{16}=1+\frac{5}{16} 其中516=1165\frac{5}{16}=\frac{1}{\frac{16}{5}},即2116=1+516=1+1165\frac{21}{16}=1+\frac{5}{16}=1+\frac{1}{\frac{16}{5}}。由此我们得到a1=1a_1=1。 考虑右下方165\frac{16}{5},又是形如2116\frac{21}{16}的式子,继续化简得到:165=3+15\frac{16}{5}=3+\frac{1}{5},由此我们得到a2=3,a3=5a_2=3,a_3=5。 其中,终止条件为某次得到分数的分子为11。如3+153+\frac{1}{5}中的15\frac{1}{5}的分子为11,其已符合a1+1a2+1a3+1a4+1a_1+\frac{1}{a_2+\frac{1}{a_3+\frac{1}{a_4+\frac{1}{\cdots}}}}的形式。


注意事项

  • 为避免精度误差,可以使用字符串来处理输入的数据
  • 题目未规定数据一定是小数,若使用字符串来处理,可能不存在小数点'.'

AC代码

/*
 * @Author: LetMeFly
 * @Date: 2021-04-28 22:33:39
 * @LastEditors: LetMeFly
 * @LastEditTime: 2021-04-28 23:02:25
 */
#include <bits/stdc++.h>
using namespace std;
#define mem(a) memset(a, 0, sizeof(a))
#define dbg(x) cout << #x << " = " << x << endl
#define fi(i, l, r) for (int i = l; i < r; i++)
#define cd(a) scanf("%d", &a)
typedef long long ll;
int main()
{
    string ori; // original代表原始数据
    cin >> ori;
    ll numerator, denominator;      // 分子分母
    if (ori.find('.') < ori.size()) // 数据中有小数点,是非整数
    {
        int location = ori.find('.');
        denominator = pow(10, ori.size() - location - 1);
        numerator = atoll((ori.substr(0, location) + ori.substr(location + 1, ori.size() - location - 1)).c_str());
    }
    else // 直接是整数
    {
        numerator = atoll(ori.c_str());
        denominator = 1;
    }
    ll gcd = __gcd(numerator, denominator); // 约分
    numerator /= gcd, denominator /= gcd;
    while (denominator != 1) // 分母不为1时(倒数分子不为1时)
    {
        ll mod = numerator / denominator;
        cout << mod << ' ';
        numerator -= mod * denominator;
        swap(numerator, denominator);
    }
    cout << numerator << endl;
    return 0;
}

同步发文于我的CSDN,原创不易,转载请附上原文链接哦~
Tisfy:letmefly.blog.csdn.net/article/det…