先不谈解这个题,这个题将我的思绪带回了小学时候第一次知道循环小数的时候。
但是这些知识随着长大而慢慢忘记,今天恶补了一些关于循环节的知识了。
相比于解题,这个可能更令人开心吧。
以下内容引用这篇博客:<<我对循环节的研究小结>>。
设a、b为正整数,a,b互为质数,b中有2,5之外的质因子,则a/b必然会产生循环节。
我自己知道的知识则是:任何一个循环小数都可以表示成为一个分数,这个也和这个理论相符合。
以下:
1.用竖式做出发除法时候,会不断产生‘商和余数’,由于余数只可能有b种,任意一种余数循环而碰面即循环节的长度不会超过b的位数(1~b-1),例如1/7=0.142857142587...是6位。
不过好像确实也是这样的,1/7,其被除数分别为 1 3 2 6 4 5 1,被除数再次出现的时候,产生了循环节142857。
41/468=0.08(760683)
2.循环节的后面不再会有非循环节的数存在。
3.第一个循环节前的全部小数,在这里称为前导小数.循环节的长度是指一个循环节的位数,设d=前导小数的位数+循环节的长度,则d计算中,a/b的第d位后的各位对应的余数各不相同,则前导小数的各位对应的余数绝不会在a/b的第d位后的各位对应的
4.循环节循环的原因就是其各位对应的余数复现,复现一个余数后,其他自然是毫无悬念的复现。
5.余数中复现,原因是0和余数不一定是一一对应关系。
6.若存在前导小说,则计算中判断第二个循环节的开始位置变得很困难。
上面是正式解题前做的一些工作,补充了一些关于循环节的知识:感觉还有用了一些时间的。
这个题做了好久,但是到现在还是WA,我自己实在找不出错误在哪里了,下面贴上代码,大佬如果有时间,能否帮我看看,不胜感激。
#include<stdio.h>
#include<string.h>
#define maxn 3000+10
int remainder[maxn];
int quotient[maxn];
int main() {
int a, b;
while (scanf("%d %d", &a, &b) == 2 && b) {
getchar();
quotient[0] = a / b;
remainder[0] = a % b;
int xn = -1, len = -1;
for (int i = 1; i < maxn; i++) {
quotient[i] = remainder[i - 1] * 10 / b;
remainder[i] = remainder[i - 1] * 10 % b;
for (int j = 0; j<i; j++) {
if (quotient[j] == quotient[i] && remainder[j] == remainder[i])
{
xn = j;
len = i - j;
break;
}
}
if (xn != -1 && len != -1) break;
}
printf("%d/%d = %d.", a, b, quotient[0]);
for (int i = 1; i < xn ; i++)
printf("%d", quotient[i]);
printf("(");
for (int i = xn; i <= xn + len -1 && i<=50; i++)
{
if(i - xn < 50 - xn +1)
printf("%d", quotient[i]);
else {
printf("...");
break;
}
}
printf(")\n");
printf(" %d = number of digits in repeating cycle\n\n", len);
}
return 0;
}