循环小数——模拟除法

题目

输入整数a和b(0 ≤ a ≤ 3000,1 ≤ b ≤ 3000),输出a / b的循环小数表示以及循环节的长度。例如a = 5,b = 43,小数表示为0.(116279069767441860465),循环节的长度为21。

解题思路

用模拟除法,并用数组模拟每次存储每次相除的结果,每除一次与前面的所有元素比较一次,如果与数组中某一元素相等,即可停止循环,因为此时循环节已经找到,并用变量m、n分别记录循环节的起始和终止位置,然后就是按规定的格式输出。

代码实现

 1 #include<stdio.h>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 
 7 const int maxn = 3000 + 10;
 8 int a, b;
 9 int frac[maxn],pos[maxn],yu[maxn];
10  
11 int main()
12 {
13     while (scanf("%d%d",&a,&b) == 2)
14     {
15         int tmp = a;
16         memset(frac, 0, sizeof(frac));
17         memset(pos, 0, sizeof(pos));
18         memset(yu, 0, sizeof(yu));
19 
20         int cnt = 0;
21         frac[cnt++] = a / b;
22         a = a % b;
23 
24         while (!pos[a] && a)
25         {
26             yu[cnt] = a;             //记录每个余数
27             pos[a] = cnt;            //记录每个余数的位置
28             frac[cnt++] = (a * 10) / b;    //记录商
29             a = (a * 10) % b;
30         }
31 
32         printf("%d %d = %d.", tmp, b, frac[0]);
33         for (int i = 1; i <= 50 && i < cnt; i++)
34         {
35             if (a & yu[i] == a)  printf("(");  //利用了循环节前一个和循环节最后一个的余数相同
36             printf("%d", frac[i]);
37         }
38         if (!a)
39             printf("(0");
40         if (cnt > 50)
41             printf("...");
42         printf(")\n");
43         printf("   %d = number of digits in repeating cycle\n\n", a == 0 ? 1 : cnt - pos[a]);
44     }
45     return 0;
46 }

参考链接:https://blog.csdn.net/qiweigo/article/details/43051043

猜你喜欢

转载自www.cnblogs.com/lfri/p/9726513.html