蓝桥杯 历届真题 有理数的循环节【国赛】【本科组】

题目描述

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

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

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

输入描述

输入一行,两个整数。

每个整数范围均为:1 ~ 1000。

输出描述

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

输入输出样例

示例

输入

1,7

输出

0.[142857]

算法思路

这是一道数学题,首先要明确一下两数相除怎么区分小数部分和整数部分。我们不难得出一点规律:答案的整数部分为:x/y 答案的小数部分为:(x%y)/1.0/y 第一部分不难得出,我们主要看一下第二部分。 除法的小数部分可以很容易由两个递推式求得:

result=x*10 / y

x=x*10%y

将result定义为一个数组由下标控制就可以很容易保存结果。 接下来就是确定循环节的位置,首先根据输入输出,也不难看出,我们只需要计算到循环节的末尾就没必要再计算下去了,这里可以作为循环的边界。”]“必定输出在末尾,所以只需要确定循环节的起始位置就可以了。 什么时候它能构成一个循环呢?即,当x两次出现一样的数,在你做除法竖式的时候应该也很容易得出这个结论,如果我们在计算的时候得出一样的结果,那么很容易判断它就是个循环小数。 我们定义mod[i]为在做除法运算时出现余数i的位置,即余数i第一次出现在mod[i]的位置,当第二次出现这个余数的时候,判断循环节在该余数第一次出现的位置开始。

 代码如下

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int x, y;
    scanf("%d,%d", &x, &y);
     int num[1000] = {0}, mod[1000] = {0};
    num[0] = x / y;
    int flag = 0, i = 1, circle;
    int m = x % y;
    while (flag == 0)
    {
        mod[m] = i;
        num[i] = m * 10 / y;
        m = m * 10 % y;
        if (m == 0)
        {
            flag = 1;
        }
        if (mod[m])
        {
            flag = 2;
            circle = m;
        }
        i++;
    }
    cout << num[0] << '.';
    for (size_t j = 1; j < i; j++)
    {
        if (flag == 2 && mod[circle] == j)
        {
            cout<<'[';
        }
        cout<<num[j];
    }
    if (flag==2)
    {
       cout<<']';
    }
    system("pause");
    return 0;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值