题目简介:
输入整数 a 和 b ( a 属于[ 0, 3000 ],b 属于[ 1, 3000 ] ),输出 a / b 的循环小数表示以及循环节长度。例如 a = 5,b = 43,小数表示为0.(116279069767441860465),循环节长度为 21。
样例及原理:
这里不妨取 a = 50,b = 7,来举例子
如何判定循环节的起始呢?我们回到最基本的除法竖式来寻找答案
不难发现,如果得到的余数和之前某次运算得到的余数相等,那么以下的运算又回到原来的圈圈里了,如法炮制。这就是进入了循环节。
同理,有限小数的余数肯定是以0结尾,以0结尾之后的余数我们仍可以看作是0,所以运用这套方法也是可以的,不必另起炉灶。
参考代码:
//有理数之间相除得到的商
//1.要么是有限的 2.要么是无限循环的
#include <stdio.h>
#define maxn 10010
int main()
{
int a, b;
while (scanf("%d%d", &a, &b)!= EOF){
int r[maxn], ans[maxn];
ans[0] = a / b;
int i;
r[0] = a - (b * ans[0]);
int start, end, len;
for (i = 1; ; i ++){
ans[i] = r[i - 1] * 10 / b;
r[i] = r[i - 1] * 10 - ans[i] * b;
int j;
int ok = 0;
for (j = 0; j < i; j ++){
if (r[i] == r[j]){
start = j + 1;
end = i;
len = i - j;
ok = 1;
break;
}
}
if (ok == 1){
break;
}
}
printf("%d/%d = %d.", a, b, ans[0]);
for (i = 1; i < start; i ++){
printf("%d", ans[i]);
}
printf("(");
for (i = start; i<=end && i<start+50; i ++){
printf("%d", ans[i]);
}
if (len > 50) printf("...");
printf(")\n");
printf(" %d = number of digits in repeating cycle\n\n", len);
}
return 0;
}