Description
The decimal expansion of the fraction 1/33 is , where the is used to indicate that the cycle 03 repeats indefinitely with no intervening digits. In fact, the decimal expansion of every rational number (fraction) has a repeating cycle as opposed to decimal expansions of irrational numbers, which have no such repeating cycles.
Examples of decimal expansions of rational numbers and their repeating cycles are shown below. Here, we use parentheses to enclose the repeating cycle rather than place a bar over the cycle.
Write a program that reads numerators and denominators of fractions and determines their repeating cycles.
For the purposes of this problem, define a repeating cycle of a fraction to be the first minimal length string of digits to the right of the decimal that repeats indefinitely with no intervening digits. Thus for example, the repeating cycle of the fraction 1/250 is 0, which begins at position 4 (as opposed to 0 which begins at positions 1 or 2 and as opposed to 00 which begins at positions 1 or 4).
Input
Each line of the input file consists of an integer numerator, which is nonnegative, followed by an integer denominator, which is positive. None of the input integers exceeds 3000. End-of-file indicates the end of input.
Output
For each line of input, print the fraction, its decimal expansion through the first occurrence of the cycle to the right of the decimal or 50 decimal places (whichever comes first), and the length of the entire repeating cycle.
In writing the decimal expansion, enclose the repeating cycle in parentheses when possible. If the entire repeating cycle does not occur within the first 50 places, place a left parenthesis where the cycle begins - it will begin within the first 50 places - and place ``...)" after the 50th digit.
Print a blank line after every test case.
Sample Input
76 25 5 43 1 397
Sample Output
76/25 = 3.04(0) 1 = number of digits in repeating cycle 5/43 = 0.(116279069767441860465) 21 = number of digits in repeating cycle 1/397 = 0.(00251889168765743073047858942065491183879093198992...) 99 = number of digits in repeating cycle
Solution
题目的大意是求出小数中的循环节和循环节的长度。
我一开始的时候想到的是直接求,但是会有精度问题和循环节的判断问题。
然后对于精度的话可以用移位的想法,就是每次*10之后取出那一位小数的值,接下去继续*10,中间要记得把小数去掉(其实就是变成整数之间的除法)
至于循环节的判断,我找到了一个比较巧妙的方法(借鉴他人),就是直接判断当前的数之前有没有做过运算,有的话就是循环节的起点了。
比如说1/6的话,变成10/6=1……4,变成0.1,40/6=6……4, 也就是0.16,这个时候4又出现了,就说明接下去的运算都将是循环的了,我们就可以知道循环节是6
其实这就是把除法运算直接模拟的。
#include <cstdio>
#include <cstring>
int vis[50005], ans[50005];
int main()
{
int a, b;
while (scanf("%d%d", &a, &b) == 2)
{
int i, j, k, zhen;
bool has = false;
memset(vis, 0, sizeof(vis));
memset(ans, 0, sizeof(ans));
i = a;
zhen = i/b;
i = i % b * 10;
j = k = 0;
while (i)
{
if (vis[i]) //判断是否之前计算过
{
has = true;
break;
}
ans[k++] = i*1.0/b;
vis[i] = k; //记录这次计算结果的
i = i % b *10;
}
printf("%d/%d = ", a, b);
if (!has) //没有循环节
{
printf("%d.", zhen);
for (j = 0; j < k; ++j) printf("%d", ans[j]);
printf("(0)\n 1 = number of digits in repeating cycle\n\n");
}
else
{
printf("%d.", zhen);
for (j = 0; j < k; ++j) //输出循环节的时候的格式控制
{
if (j == vis[i]-1) printf("(");
if (j < 50) printf("%d", ans[j]);
else
{
printf("...");
break;
}
}
printf(")\n %d = number of digits in repeating cycle\n\n", k-vis[i]+1);
}
}
return 0;
}