题目描述
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;
}