其他分享
首页 > 其他分享> > 【蓝桥杯】有理数的循环节

【蓝桥杯】有理数的循环节

作者:互联网

有理数的循环节

1 / 7 = 0.142857142 ⋯ ⋯ 1/7 = 0.142857142 \cdots\cdots 1/7=0.142857142⋯⋯ 是个无限循环小数。

任何有理数都可以表示为无限循环小数的形式。

题目要求即是:给出一个数字的循环小数表示法。

输入描述
输入一行,两个整数。
每个整数范围均为:1 ~ 1000。

输出描述
输出两个整数做除法产生的小数或无限循环小数(循环节用方括号括起)。

输入输出样例
示例
输入

1,7

输出

0.[142857]

思路

到这里,可能已经看出规律了,再继续除下去的话就循环起来了,则已经找出了循环节

代码如下

#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;

unordered_map<int, int> mp;  //余数<->下标
vector<int> data;            //存放小数部分的数组
int n, m;                    //分子,分母

void solve() {
    int res = 0;  //整数部分商
    int t = 0;    //下标
    scanf("%d,%d", &n, &m);//坑点,要把逗号加进去
    //处理整数部分
    res = n / m;
    n %= m;
    mp[n] = t++;
    //处理小数部分
    while (true) {
        if (n == 0) {
        //这是除得尽的情况
            printf("%d.", res);//整数部分
            //小数部分全部输出
            for (int i = 0; i < int(data.size()); i++) {
                printf("%d", data.at(i));
            }
            printf("\n");
            break;
        }
        n *= 10;//添0继续除
        data.push_back(n / m);//商
        n %= m;//余数更新被除数
        //余数不为0且余数出现过
        if (n && mp.find(n) != mp.end()) {
            printf("%d.", res);//输出整数部分
            //输出循环节之前的小数部分,有些循环小数要等几个数之后才开始循环
            for (int i = 0; i < mp[n]; i++) {
                printf("%d", data.at(i));
            }
            //输出循环节
            printf("[");
            for (int i = mp[n]; i < (int)data.size(); i++) {
                printf("%d", data.at(i));
            }
            printf("]\n");
            break;
        } else {
        //否则加入
            mp[n] = t++;
        }
    }
}

int main(void) {
    solve();
    return 0;
}

标签:有理数,int,蓝桥,循环,mp,printf,余数,data
来源: https://blog.csdn.net/m0_52319522/article/details/122816020