东华OJ-基础题-124-分数化小数(C++)-难度中

  • 问题描述
    写一个程序,输入一个形如N/D的分数(N是分子,D是分母),输出它的小数形式。

如果小数有循环节的话,把循环节放在一对圆括号中。

例如, 1/3 = .33333333 写成0.(3)

41/333 = 0.123123123... 写成0.(123)

用xxx.0 表示整数

典型的转化例子: 1/3 = 0.(3)

22/5 = 4.4

1/7 = 0.(142857)

2/2 = 1.0

3/8 = 0.375

45/56 = 0.803(571428)

  • 输入说明
    单独的一行包括被空格分开的 N和D, 1 <= N,D <= 100000。
  • 输出说明
    小数的表示方法上面说的很明白了,如果输出的长度超过76个字符,每行输出76个字符(包括小数点、括号等)。
  • 输入范例
cpp 复制代码
45 56
  • 输出范例
cpp 复制代码
0.803(571428)

感想:用哈希表记录余数数字的位置,一旦再碰到同样的余数,记录下该位置,方便之后加括号。

代码如下:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

void output_decimal(int n,int d) {
    string res;
    string int_part;
    int_part = to_string(n/d);
    int remainder = n%d;
    res = int_part+".";

    vector<char>decimal_digits;
    unordered_map<int, int> remainder_pos; // 余数→小数位的位置(记录首次出现位置)
    int repeat_pos = -1; // 循环节起始位置(-1表示无循环)

    while (remainder != 0) {
        // 检查余数是否已出现(检测循环节)
        if (remainder_pos.find(remainder) != remainder_pos.end()) {
            repeat_pos = remainder_pos[remainder]; // 循环节起始位置
            break;
        }
        remainder_pos[remainder] = decimal_digits.size(); // 记录当前余数的位置

        remainder *= 10;
        int digit = remainder / d;
        decimal_digits.push_back('0' + digit);
        remainder = remainder % d;
    }

    for (int i = 0; i < decimal_digits.size(); ++i) {
        // 循环节起始位置,添加左括号
        if (i == repeat_pos) {
            res += "(";
        }
        res += decimal_digits[i];
    }
    // 有循环节则添加右括号
    if (repeat_pos != -1)
        res += ")";
    // 无小数位(余数为0且无循环),补充.0(如2/2=1.0)
    else if (decimal_digits.empty()) {
        res += "0";
    }


    int cnt = 0;
    for(size_t i=0; i<res.size(); ++i) {
        ++cnt;
        if(cnt%76 == 0) {
            cout<<res[i];
            cout<<endl;
        } else
            cout<<res[i];
    }

}

//Tips:所有分数(有理数)的小数形式只能是 "有限小数" 或 "无限循环小数",不存在无限不循环的分数
//Tips:无限不循环小数(如 π、√2)是无理数,无法表示为两个整数的比值
int main() {
    int n,d;
    cin>>n>>d;
    output_decimal(n,d);
    return 0;
}
相关推荐
小马过河R17 分钟前
EdgeOne深度解析:从原理、适用场景到COS接入的技术逻辑
java·开发语言·前端·spring·cos
多弗朗皮卡丘25 分钟前
C++ 红黑树
开发语言·c++·红黑树
ZoeLandia35 分钟前
TypeScript 04:类型断言与类型守卫
开发语言·前端·typescript
geovindu1 小时前
rust: pool Pattern
开发语言·后端·设计模式·rust·对象池简写模式
鶴哥只手遮天1 小时前
《OpenFOAM 源码深度剖析》系列-第 3 章 字典系统、IO 体系与对象注册表
算法·开源
鶴哥只手遮天1 小时前
《OpenFOAM 源码深度剖析》系列-第 2 章 wmake:OpenFOAM 自研构建系统与编译配置体系
算法·开源
用户81849100742161 小时前
我把工位上的“AI牛马”养成了:一个技术人的 AiPy 实战手记
算法
Tisfy1 小时前
LeetCode 3727.最大交替平方和:排序 (双指针可选)
算法·leetcode·题解·贪心·数组·排序
鶴哥只手遮天1 小时前
《OpenFOAM 源码深度剖析》系列-第 9 章 有限体积离散框架:`fvMatrix`、`fvSchemes` 与 `fvSolution`
算法·开源
鶴哥只手遮天1 小时前
《OpenFOAM 源码深度剖析》系列-第 7 章 网格与拓扑体系:`polyMesh`、`primitiveMesh` 与 patch
算法·开源